使用Golang RSA包解密Dart加密内容时出现解密错误
问题:Dart/Flutter encrypt RSA加密后Golang解密失败:
crypto/rsa: decryption error 问题场景
使用Dart/Flutter的encrypt包对字符串加密,代码如下:
Future<String> encryptPIN({required String pin}) async { final RSAPublicKey publicKey; final publicPem = await rootBundle.loadString('assets/keys/private-key.pem'); publicKey = RSAKeyParser().parse(publicPem) as RSAPublicKey; final encrypter = Encrypter(RSA(publicKey: publicKey, encoding: RSAEncoding.OAEP)); final encryptedPIN = encrypter.encrypt(pin).base64; return encryptedPIN; } }
随后用Golang解密,代码如下:
func Decrypt(rsaPrivateKey *rsa.PrivateKey, cipherText []byte) []byte { hash := sha256.New() r := rand.Reader label := []byte(nil) decryptedSum, err := rsa.DecryptOAEP(hash, r, rsaPrivateKey, cipherText, label) if err != nil { panic(err) } return decryptedSum }
Dart加密正常,但Golang解密报错crypto/rsa: decryption error。
错误原因及修正方案
1. 密钥文件误用:私钥被当作公钥加载
RSA加密遵循公钥加密、私钥解密的规则,你的Dart代码加载的是private-key.pem却解析为RSAPublicKey,属于密钥类型混淆,应改为加载公钥文件(如public-key.pem)。
2. OAEP哈希算法不匹配
encrypt包的RSA OAEP默认使用SHA-1哈希,而你的Go代码使用SHA-256,哈希算法不一致会导致解密失败,需在Dart端指定SHA-256与Go端对齐。
3. 解密前缺少Base64解码步骤
Dart端将加密结果转为Base64字符串返回,Go端解密前必须先将该Base64字符串解码为字节数组,再传入解密函数。
修正后的代码
Dart端代码
Future<String> encryptPIN({required String pin}) async { final RSAPublicKey publicKey; // 加载正确的公钥文件 final publicPem = await rootBundle.loadString('assets/keys/public-key.pem'); publicKey = RSAKeyParser().parse(publicPem) as RSAPublicKey; // 指定SHA-256哈希,与Go端保持一致 final encrypter = Encrypter(RSA( publicKey: publicKey, encoding: RSAEncoding.OAEP, hash: SHA256(), )); final encryptedPIN = encrypter.encrypt(pin).base64; return encryptedPIN; }
Golang端补充Base64解码逻辑
import ( "crypto/rand" "crypto/rsa" "crypto/sha256" "encoding/base64" "errors" ) func DecryptBase64(rsaPrivateKey *rsa.PrivateKey, base64CipherText string) ([]byte, error) { // 先解码Base64格式的密文 cipherText, err := base64.StdEncoding.DecodeString(base64CipherText) if err != nil { return nil, errors.New("base64 decode failed: " + err.Error()) } hash := sha256.New() label := []byte(nil) decryptedSum, err := rsa.DecryptOAEP(hash, rand.Reader, rsaPrivateKey, cipherText, label) if err != nil { return nil, errors.New("rsa decrypt failed: " + err.Error()) } return decryptedSum, nil }
内容的提问来源于stack exchange,提问作者Margach Chris
相关产品推荐
相关产品推荐

