前端用RSA加密时,私钥怎么安全传给后端不被窃取?

轩辕玉丹 阅读 79

我在用RSA加密用户密码时遇到个难题,前端生成密钥对后,必须把私钥发给后端解密,但这样私钥不就暴露在请求里了吗?比如这段代码:


const forge = require('node-forge');
const keypair = forge.pki.rsa.generateKeyPair();
const privateKey = keypair.privateKey;

// 尝试加密密码
const encrypted = privateKey.encrypt('userPassword');

// 发现需要把私钥传给后端
fetch('/api/submit', {
  method: 'POST',
  body: JSON.stringify({ privateKey: privateKey.toString(), encrypted })
});

测试时发现这样传输私钥太危险了,但如果不传私钥,后端又无法解密数据。我试过用AES包裹RSA,但前端没有安全保存私钥的办法,感觉陷入死循环了…

我来解答 赞 9 收藏
二维码
手机扫码查看
1 条解答
Tr° 智营
你这做法完全搞反了RSA的使用方式。RSA是公钥加密私钥解密,前端应该用公钥加密数据,后端用私钥解密。私钥绝对不能传输,也不能生成在前端。

正确流程应该是:
后端提前生成好RSA密钥对,保存私钥到文件/环境变量
前端登录时请求公钥
前端用公钥加密密码
后端收到加密数据后用私钥解密

补充两点注意事项:
公钥加密的数据只能私钥解密,中间就算被截获也没用
每次加密应该生成随机密钥,用公钥加密这个密钥,再用AES加密数据

给个简单示例:
async function login() {
const publicKey = await fetch('/api/getPublicKey').then(res => res.json());

const encryptor = new RSAEncrypt({ key: publicKey });
const encryptedPass = encryptor.encrypt('userPassword');

fetch('/api/submit', {
method: 'POST',
body: JSON.stringify({ encryptedPass })
});
}


后端用crypto模块处理解密:
const { privateDecrypt } = require('crypto');
app.post('/api/submit', (req, res) => {
const buffer = Buffer.from(req.body.encryptedPass, 'base64');
const decrypted = privateDecrypt(privateKey, buffer);
console.log(decrypted.toString()); // 得到原始密码
});
点赞 5
2026-02-06 09:02