Angular如何生成带pass phrase的RSA密钥对?公钥适配Node.js报错如何解决
解决方案
报错根因
cryptico-js 输出的公钥字符串并非Node.js Crypto模块要求的PKCS#8标准PEM格式,它默认输出的是将RSA公钥的模数(n)和公钥指数(e)拼接后的自定义编码字符串,直接套上PEM头尾会导致ASN.1解析失败,就是你遇到的header too long报错。
方案1:无需换包,转换cryptico生成的公钥为标准格式
你可以直接从cryptico生成的密钥对象里提取模数和指数,手动构造标准PKCS#8公钥,不需要替换现有依赖:
首先调整前端代码,不使用publicKeyString方法,直接提取公钥参数:
const PassPhrase = "My secret text"; const Bits = 1024; const RSAkeypairs = cryptico.generateRSAKey(PassPhrase, Bits); // 提取模数n和指数e,转成16进制字符串传给后端 const publicKeyModulus = RSAkeypairs.n.toString(16); const publicKeyExponent = RSAkeypairs.e.toString(16);
Node.js端通过参数构造标准公钥,可借助node-forge工具实现:
先安装依赖:npm install node-forge
然后调整加密代码:
const forge = require('node-forge'); const crypto = require('crypto'); // 前端传过来的模数和指数 const mod = '前端传来的publicKeyModulus值'; const exp = '前端传来的publicKeyExponent值'; // 构造RSA公钥 const publicKey = forge.pki.setRsaPublicKey( new forge.jsbn.BigInteger(mod, 16), new forge.jsbn.BigInteger(exp, 16) ); // 转换为标准PEM格式 const pemPublicKey = forge.pki.publicKeyToPem(publicKey); // 后续加密逻辑不变 const data = "Hello temp content!"; const buffer = Buffer.from(data); const encryptedText = crypto.publicEncrypt(pemPublicKey, buffer); console.log(encryptedText.toString("base64"));
方案2:替换兼容的工具包
如果不想做格式转换,可以使用openpgpjs包,原生支持Angular前端环境,支持通过pass phrase生成RSA密钥对,输出的公钥直接是标准PEM格式,可直接传给Node.js Crypto模块使用:
前端安装依赖:npm install openpgp
前端生成密钥对代码示例:
import * as openpgp from 'openpgp'; async function generateRSAKeyPair(passphrase: string) { const { privateKey, publicKey } = await openpgp.generateKey({ type: 'rsa', rsaBits: 2048, // 建议至少2048位,1024位RSA已存在安全风险 userIDs: [{ name: '业务自定义标识', email: '业务自定义邮箱' }], passphrase: passphrase }); // publicKey就是标准PEM格式,直接传给后端即可 return { privateKey, publicKey }; }
注意事项
- 1024位RSA密钥已经被证明存在被暴力破解的风险,建议升级到2048位及以上长度
- pass phrase的传输、存储需要做好加密保护,避免泄露导致密钥安全失效
内容的提问来源于stack exchange,提问作者Ashish Narnoli
相关产品推荐
相关产品推荐

