背景:前端用户登录时密码明文传输,要求密码加密传输。选择 RSA,前后端技术栈
Vue
+NodeJS
RSA也就是非对称加密,有公钥和私钥。公钥由服务器给出,可以被所有人知道,而私钥不能泄露,只能被服务器知道。
RSA大概工作流程:
- 前端拿到服务器给出的公钥
- 前端使用公钥对密码明文进行加密得到密文
- 发送密文到服务器
- 服务器用私钥对其进行解密,就能得到密码的明文
由于用的是 NodeJS
和 Vue
,前后端统一使用 NodeJS
自带的 crypto,方便统一
前端
- 引入 crypto 的使用公钥加密的方法
import {publicEncrypt} from 'crypto'
- 从后端请求公钥
const publicKey = api.getKey() // 这里是一个封装后的方法,就不写详细实现了
- 对密码明文进行加密
// 第一个参数是公钥,第二个参数是要加密的数据,接收一个 Buffer 类型的参数,返回值同样是 Buffer,为了方便传输转换成 base64 编码的字符串
const rsaPassword = publicEncrypt(publicKey, Buffer.from(password)).toString('base64')
这样前端就完成了
后端
- 首先导入生产公私钥以及解密的方法
const {generateKeyPairSync, privateDecrypt} = require('crypto')
- 生成公、私钥
const {publicKey, privateKey} = generateKeyPairSync('rsa', {
modulusLength: 1024,
publicKeyEncoding: {
type:'pkcs1',
format:'pem'
},
privateKeyEncoding: {
type:'pkcs1',
format:'pem'
}
})
- 获取公钥 给前端生成密文
const getPublicKey = () => {
return publicKey
}
- 解密(加密在前端,后端只需要解密就好了)
const decrypt = (data) => {
// 同样需要转化成base64编码的Buffer
const bufferData = Buffer.from(data, 'base64')
return privateDecrypt(privateKey, data).toString()
}
接下来只要在前端请求公钥的时候返回上面生成的公钥,然后在前端传来密码后调用decrypt
方法进行解密就可以得到密码的明文了。 over
参考: https://blog.csdn.net/zhai_865327/article/details/105588930
tips:这个公钥私钥是每次请求都会生成新的,如果有并发请求可能会出现问题