为什么RSA加密后的数据在服务端解密总是报错?

UX钰岩 阅读 66

我用前端的jsencrypt库做了RSA加密,后端用node.js的crypto模块解密,但一直报错说“error:040…数据无效”。加密用的是公钥文件里的—–BEGIN PUBLIC KEY—–格式内容,解密时用的是对应的私钥。明明密钥对是自己生成的,哪里出问题了?

前端代码是这样写的:const encrypt = new JSEncrypt(); encrypt.setPublicKey(pubKey); let encrypted = encrypt.encrypt(data);

后端用的是这段:

const crypto = require('crypto');
const privateKey = fs.readFileSync('private.key');
crypto.privateDecrypt({
  key: privateKey,
  padding: crypto.constants.RSA_PKCS1_OAEP_PADDING
}, Buffer.from(req.body.encrypted, 'base64'))

尝试过把前端加密的padding参数改了,但库好像不支持设置…难道是密钥格式不对?或者加密解密的padding方式不一致?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
夏侯艳花
问题很明显,你后端用的是OAEP padding,但JSEncrypt默认用的是PKCS1 padding,这就对不上。

改一下后端代码,把OAEP改成PKCS1:

const crypto = require('crypto');
const privateKey = fs.readFileSync('private.key');

crypto.privateDecrypt({
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PADDING // 改成这个
}, Buffer.from(req.body.encrypted, 'base64'))


如果你非要两边都用OAEP,那JSEncrypt那边可以这样设置:

const encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
encrypt.setEncryptionScheme('oaep'); // 加这行
let encrypted = encrypt.encrypt(data);


不过说实话,PKCS1足够用了,改后端一行代码就能解决的事儿,没必要折腾前端。

另外提醒一下,JSEncrypt默认密钥长度是1024bit,现在看来有点短了,生成密钥的时候建议用2048bit。
点赞
2026-03-14 12:07
慧利 Dev
问题出在padding方式不一致,前端JSEncrypt默认使用PKCS1 v1.5填充,而后端用的是OAEP。改后端解密参数为RSA_PKCS1_PADDING就对了。

crypto.privateDecrypt({
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PADDING
}, Buffer.from(req.body.encrypted, 'base64'))
点赞 7
2026-02-04 08:16