Node.js RSA加密数据后前端JS解密失败,报malformed utf8 data错误求助
Node.js RSA加密后前端解密出现「malformed utf8 data」错误的解决方案
问题背景
在Node.js中使用RSA公钥加密数据,将私钥传输到前端后,用JSEncrypt解密时始终出现「malformed utf8 data」错误,多次尝试无法解决。
核心原因
- 填充方式不兼容:Node.js的
crypto模块默认使用RSA_PKCS1_OAEP_PADDING填充,但JSEncrypt默认仅支持RSA_PKCS1_V1_5(即PKCS1-PADDING),两者不匹配导致解密失败。 - 私钥格式损坏:EJS渲染私钥时使用
<%= %>会自动转义HTML特殊字符,导致私钥的PEM格式丢失换行符,无法被JSEncrypt正确识别。
修复步骤及代码示例
1. 修改Node.js端加密逻辑,统一填充方式
将加密和解密的填充方式改为RSA_PKCS1_PADDING,与JSEncrypt兼容:
const crypto = require('crypto'); function generate_key() { const keys = crypto.generateKeyPairSync('rsa', { modulusLength: 2048, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); const { privateKey, publicKey } = keys; return { privateKey, publicKey }; } function enc(plainText, publicKey) { const buffer = Buffer.from(plainText, 'utf-8'); const encrypted = crypto.publicEncrypt( { key: publicKey, padding: crypto.constants.RSA_PKCS1_PADDING }, // 改用PKCS1-V1_5填充 buffer ); return encrypted.toString('base64'); } // Node.js端解密测试(验证加密正确性) function dec(cipherText, privateKey) { const buffer = Buffer.from(cipherText, 'base64'); const decrypted = crypto.privateDecrypt( { key: privateKey, padding: crypto.constants.RSA_PKCS1_PADDING }, // 匹配填充方式 buffer ); return decrypted.toString('utf-8'); } // 业务逻辑示例 let { privateKey, publicKey } = generate_key(); const plaintext = 'This is the message to be encrypted'; const encrypted = enc(plaintext, publicKey); // 渲染页面时传递参数 res.render('final', { privateKey: privateKey, encrypted: encrypted });
2. 修复前端EJS渲染逻辑,保留私钥格式
使用<%- %>代替<%= %>渲染私钥和加密数据,避免HTML转义破坏格式:
<script src="/jsencrypt.min.js"></script> <script> // 用<%- %>确保私钥的PEM格式完整保留 let privateKey = `<%- privateKey %>`; let encrypted = `<%- encrypted %>`; var crypt = new JSEncrypt(); crypt.setPrivateKey(privateKey); var decrypted = crypt.decrypt(encrypted); console.log('解密结果:', decrypted); </script>
额外说明
- 如果必须使用OAEP填充,需更换支持该填充方式的前端加密库(如
forge或crypto-js),JSEncrypt原生不支持OAEP。 - 传输私钥存在安全风险,实际生产环境中不建议将私钥暴露到前端,应采用前端加密、后端解密的模式,或使用对称加密结合非对称加密的方案。
内容的提问来源于stack exchange,提问作者devil_sm
相关产品推荐
相关产品推荐

