Forge.js RSA解密后得到空字符串怎么办?

皇甫统维 阅读 26

我在用Forge.js给密码字段加密后发送到后台,但服务端说解密结果是空的。前端加密代码是这样的:


const encrypt = (data) => {
  const publicKey = forge.pki.publicKeyFromPem('');
  return forge.util.encode64(publicKey.encrypt(data, 'RSA-OAEP', { md: forge.md.sha256.create() }));
};

提交时用了encrypt(password),服务端用Java解密却报错。我试过把加密结果转成Buffer再传,但还是不行。控制台也没报错,就是解密结果空字符串…

我来解答 赞 11 收藏
二维码
手机扫码查看
2 条解答
长孙秀玲
你这个应该是填充方式对不上。前端用的是 RSA-OAEP 带 SHA-256,那后端 Java 解密也得用对应的 OAEPWithSHA256AndMGF1Padding,不能用默认的 PKCS1。很多 Java 默认是 RSA/ECB/PKCS1Padding,和你的前端不匹配,解出来就是空或者乱码。

还有个坑是 forge 的 encrypt 方法返回的是原始字节流,虽然你 base64 了,但得确保传给后端的数据没被二次处理,比如 JSON.stringify 自动转义了 +/= 这些字符,到后端 base64 就解不回来了。建议加密完先测试下字符串是否合法:

console.log(forge.util.encode64(publicKey.encrypt('test', 'RSA-OAEP', { md: forge.md.sha256.create() })))


看看输出是不是正常的 base64 字符串,有没有奇怪的换行或截断。

服务端代码注意用:

Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");


别用错算法。另外建议加个长度检查,密码太长也不能直接加密,OAEP 限制比 PKCS 更严,明文长度一般不能超过 (keySize / 8 - 2 * hashLen - 2),比如 2048 位密钥最多支持 214 字节左右,超了就得上混合加密。

最后注意安全:别在前端明文处理密码太久,加密后立刻清掉变量,防止 XSS 劫持。传输也一定走 HTTPS。
点赞 3
2026-02-10 14:12
Mc.明昊
Mc.明昊 Lv1
你这个问题是典型的前后端加密解密不兼容的情况。Forge.js 的 RSA 加密确实有点坑,尤其是跟 Java 配合的时候。

先说结论:问题可能出在 publicKey.encrypt 的参数配置上。Forge.js 默认的填充方式是 PKCS#1 v1.5,而你用的是 RSA-OAEP,这可能会导致服务端无法正确解析。

根据 Forge.js 的文档和最佳实践,建议你这样改:

const encrypt = (data) => {
const publicKey = forge.pki.publicKeyFromPem('你的公钥字符串');
// 确保使用正确的填充方式和服务端匹配
const encrypted = publicKey.encrypt(data, 'RSA-OAEP', {
md: forge.md.sha256.create(), // 使用 SHA-256 哈希算法
mgf: forge.mgf.mgf1.create(forge.md.sha256.create()) // 设置掩码生成函数
});
return forge.util.encode64(encrypted);
};


注意以下几点:
1. 公钥字符串不能为空,要把实际的公钥填进去。
2. mgf 参数必须显式指定,不然可能会导致前后端不一致。
3. 确保服务端也用了相同的填充方式(RSA-OAEP)和哈希算法(SHA-256)。

最后,建议你打印一下加密后的 Base64 字符串,手动拿去服务端测试解密,确认是不是前端的问题。如果还是不行,大概率是服务端配置不对了。
点赞 9
2026-02-01 18:06