Laravel RSA加密后ReactJS解密失败:加密块无效
RSA加密解密错误:Decryption failed: Error: Encryption block is invalid.
以下是针对Laravel(PHP)加密、React(forge)解密报错的排查和解决步骤:
1. 验证密钥对一致性
确保PHP端使用的公钥和React端使用的私钥是同一套RSA密钥对,避免跨密钥对加密解密。可以用openssl命令重新生成标准密钥对:
# 生成2048位私钥 openssl genrsa -out private.key 2048 # 从私钥导出对应公钥 openssl rsa -in private.key -pubout -out public.key
替换Laravel项目中的public.key和React端的私钥内容,确保两者匹配。
2. 修复PHP加密代码的编码问题
原代码中utf8_encode($data)可能导致编码混乱(若$data本身已是UTF-8编码),同时添加加密错误日志便于排查:
static function encrypt($data) { $publicPath = base_path('public.key'); $publicKey = file_get_contents($publicPath); // 直接使用原始数据(确保$data为UTF-8编码) if(openssl_public_encrypt($data, $encrypted, $publicKey, OPENSSL_PKCS1_PADDING)){ return base64_encode($encrypted); } // 记录openssl加密错误 error_log('Encryption error: ' . openssl_error_string()); return false; }
3. 检查RSA数据长度限制
RSA加密单块数据有长度限制:最大长度为密钥长度/8 - 11(例如2048位密钥最大支持245字节数据)。若加密内容过长,需改用混合加密方案:
- 用随机生成的AES密钥加密原始数据
- 用RSA公钥加密AES密钥
- 解密时先RSA解密出AES密钥,再用AES解密数据
4. 修复React解密的编码处理
forge解密返回的是二进制字符串,需显式转成UTF-8编码:
const decryptData = (encryptedData) => { const privateKey = forge.pki.privateKeyFromPem(key); const encryptedBuffer = forge.util.decode64(encryptedData); try { const decryptedBinary = privateKey.decrypt(encryptedBuffer, 'RSAES-PKCS1-V1_5'); // 将二进制字符串转换为UTF-8文本 return forge.util.decodeUtf8(decryptedBinary); } catch (err) { console.error('Decryption failed:', err); return null; } };
5. 验证公钥格式
确保Laravel读取的public.key是完整的PEM格式,无多余空格或换行:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz... (中间密钥内容) -----END PUBLIC KEY-----
若公钥是DER格式,需用openssl转成PEM:
openssl rsa -inform der -in public.der -pubout -out public.key
内容的提问来源于stack exchange,提问作者Lê Hoàng Quốc Thanh
相关产品推荐
相关产品推荐

