React中用Forge库按指定RSA填充加密AES密钥遇异常求助
加解密问题排查:RSA-OAEP加密后输出乱码
问题背景
从Java后端获取Base64格式的RSA公钥,需采用RSA/ECB/OAEPWithSHA-256AndMGF1Padding算法加密AES密钥,使用node-forge库实现后,得到的加密结果为乱码数据。
现有实现代码
const getPEMPublicKey = (publicKey) => { const pubKeyArr = publicKey.match(/.{1,64}/g) return '-----BEGIN PUBLIC KEY-----\n' + join(pubKeyArr, "\n") + '\n-----END PUBLIC KEY-----' } const encryptAESKey = (AESKey, publicKey) => { // encrypt data with a public key using RSAES-OAEP/SHA-256/MGF1-SHA-1 // compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding const publicKeyPem = forge.pki.publicKeyFromPem(getPEMPublicKey(publicKey)); const rsaEncryptedAesKey = publicKeyPem.encrypt(forge.util.encodeUtf8(AESKey), 'RSA-OAEP', { md: forge.md.sha256.create(), mgf1: { md: forge.md.sha1.create() } }); return rsaEncryptedAesKey }
异常输出
1]*Q^?o>Ãn±Ýut¼dªjfôUc$ÃÆ|&¾ZTW2 ×é_Í>ú;î¥äÊæ[jU.<¡X3ßöAsÑg½LD¥º&ÍaÎòuHÍGHóº@|YÀWÇöõ<ðªK ζuäÚ³©ËòøUj·töTa:/Çý/L4x]äiXéqÅAFÓÌKwL B3$aÍB>ÕwÉÿ<[ò x"ÞåXàh\÷p;w<§÷RyÈL¬ð5EÁ9¿´,_Ö½<Áy×ÇÁÖ6
后端提供的Base64公钥示例
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm+m0v4JKo5lb6f6pypFG/xS4wzJEJ80m3SbXs7sTQtvgblrczyjKYm5oYOVG1onWJ8XmbEdDts/sIYBArc37xLtaOgYr480YU8aqj026qc2mblpTLkGJiye0z0LmpsoQXvqZ49UD+ZHG7PetkLgIW5H+ffw2vW4fdBi9fZU6jJ9z8dkv0PLtAZ2LEuVLAqEE6rHzmEc5EmfMy70/FCRZZShS2Yq76/qGgTzlVpzV4r4d0D83Zz+ZWIL1MISGk8x86moYzM2w+8o2N0V0cDayCQKnoEiNxSKXw3+uIyoqjR7gcdlqgWfl/Wb8G5W8TemnFkOMTuUq9tZlgoadyqxjtQIDAQAB
错误分析与解决思路
核心问题
node-forge的encrypt方法返回的是原始二进制字节流,直接输出或返回会显示为乱码,而Java后端通常期望接收Base64编码后的加密结果。此外代码中存在未定义函数的隐患。
具体修复步骤
修复PEM转换函数的语法错误
代码中join(pubKeyArr, "\n")的join未定义,需改为数组原生的join方法:const getPEMPublicKey = (publicKey) => { const pubKeyArr = publicKey.match(/.{1,64}/g) || []; // 兼容公钥长度不足64的情况 return '-----BEGIN PUBLIC KEY-----\n' + pubKeyArr.join("\n") + '\n-----END PUBLIC KEY-----'; }对加密结果进行Base64编码
将加密后的二进制字节流转换为Base64字符串,确保和Java后端的格式兼容:const encryptAESKey = (AESKey, publicKey) => { const publicKeyPem = forge.pki.publicKeyFromPem(getPEMPublicKey(publicKey)); // 注意:如果AESKey是Base64格式,需先解码为字节:const aesKeyBytes = forge.util.decode64(AESKey); const aesKeyBytes = forge.util.encodeUtf8(AESKey); // 若AESKey是明文字符串则用此,否则替换为decode64 const rsaEncryptedBytes = publicKeyPem.encrypt(aesKeyBytes, 'RSA-OAEP', { md: forge.md.sha256.create(), mgf1: { md: forge.md.sha1.create() } }); // 转换为Base64格式返回 return forge.util.encode64(rsaEncryptedBytes); }验证AES密钥输入格式
确认传入的AESKey格式:如果是Base64编码的密钥,需先用forge.util.decode64解码为字节再加密;如果是明文密钥字符串,用forge.util.encodeUtf8转换为字节即可。
兼容性验证
Java的RSA/ECB/OAEPWithSHA-256AndMGF1Padding默认MGF1散列算法为SHA-1,和代码中的配置一致,这部分无需调整;示例公钥为标准PKCS#8格式,PEM转换逻辑正确。
内容的提问来源于stack exchange,提问作者Barbara Rekowska
相关产品推荐
相关产品推荐

