在使用 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)
}