Karp 的技术博客

在使用 RSA 加密时,密文的长度受限于密钥的大小。例如,使用 1024 位密钥时,加密的明文数据大小最多为 117 字节(使用 PKCS#1 v1.5 填充)。如果要加密更大的数据,你可以使用分块加密或混合加密方案。

以下是一个使用 Go 语言的示例,展示如何处理 RSA 加密解密,特别是对大于 1024 字节的数据进行加密。

1. 使用 RSA 加密的基本步骤

  • 生成 RSA 密钥对。
  • 使用 RSA 进行加密和解密。
  • 对大数据进行分块加密。

2. 示例代码

2.1 生成 RSA 密钥对

首先,您需要生成 RSA 密钥对:

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "log"
    "os"
)

// 生成 RSA 密钥对
func generateKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
    privateKey, err := rsa.GenerateKey(rand.Reader, bits)
    if err != nil {
        return nil, nil, err
    }
    return privateKey, &privateKey.PublicKey, nil
}

// 保存私钥到文件
func savePrivateKey(filename string, priv *rsa.PrivateKey) error {
    privBytes := x509.MarshalPKCS1PrivateKey(priv)
    block := &pem.Block{
        Type:  "RSA PRIVATE KEY",
        Bytes: privBytes,
    }
    return os.WriteFile(filename, pem.EncodeToMemory(block), 0600)
}

// 保存公钥到文件
func savePublicKey(filename string, pub *rsa.PublicKey) error {
    pubBytes := x509.MarshalPKCS1PublicKey(pub)
    block := &pem.Block{
        Type:  "RSA PUBLIC KEY",
        Bytes: pubBytes,
    }
    return os.WriteFile(filename, pem.EncodeToMemory(block), 0644)
}

2.2 加密和解密函数

接下来,您可以使用以下函数进行加密和解密:

// RSA 加密
func encrypt(publicKey *rsa.PublicKey, message []byte) ([]byte, error) {
    return rsa.EncryptPKCS1v15(rand.Reader, publicKey, message)
}

// RSA 解密
func decrypt(privateKey *rsa.PrivateKey, ciphertext []byte) ([]byte, error) {
    return rsa.DecryptPKCS1v15(rand.Reader, privateKey, ciphertext)
}

2.3 处理大数据的分块加密

对于大于 117 字节的消息,需要手动分块:

// 分块加密
func encryptLargeMessage(publicKey *rsa.PublicKey, message []byte) ([][]byte, error) {
    var chunks [][]byte
    chunkSize := 117 // 根据密钥大小调整

    for i := 0; i < len(message); i += chunkSize {
        end := i + chunkSize
        if end > len(message) {
            end = len(message)
        }
        chunk, err := encrypt(publicKey, message[i:end])
        if err != nil {
            return nil, err
        }
        chunks = append(chunks, chunk)
    }
    return chunks, nil
}

// 分块解密
func decryptLargeMessage(privateKey *rsa.PrivateKey, ciphertexts [][]byte) ([]byte, error) {
    var message []byte
    for _, ciphertext := range ciphertexts {
        chunk, err := decrypt(privateKey, ciphertext)
        if err != nil {
            return nil, err
        }
        message = append(message, chunk...)
    }
    return message, nil
}

2.4 示例主程序

将所有代码组合在一起,生成密钥并进行加密解密:

func main() {
    // 生成密钥对
    privateKey, publicKey, err := generateKeyPair(1024)
    if err != nil {
        log.Fatal(err)
    }

    // 保存密钥
    savePrivateKey("private.pem", privateKey)
    savePublicKey("public.pem", publicKey)

    // 要加密的消息
    message := []byte("这是一条长消息,超过了 RSA 的直接加密限制。" +
        "如果消息很长,这里需要分块处理。")

    // 分块加密
    ciphertexts, err := encryptLargeMessage(publicKey, message)
    if err != nil {
        log.Fatal(err)
    }

    // 分块解密
    decryptedMessage, err := decryptLargeMessage(privateKey, ciphertexts)
    if err != nil {
        log.Fatal(err)
    }

    // 输出结果
    log.Printf("解密后的消息: %s\n", decryptedMessage)
}

版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2024年10月21日 07:50
0

目录

来自 《RSA密文过长加密解密 越过1024的解决代码》
774 文章数
0 评论量
9 分类数
779 页面数
已在风雨中度过 9年279天5小时46分