背景:前端用戶登錄時密碼明文傳輸,要求密碼加密傳輸。選擇 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:這個公鑰私鑰是每次請求都會生成新的,如果有並發請求可能會出現問題