RSA是一种非对称加密,也就是客户端通过公钥进行加密,服务端通过私钥进行解密。 RSA算法请点击维基百科RSA加密演算法进行了解。
也就是说公钥并不能进行解密,因此进行明文传输也是安全的。
技术栈
node-rsa
安装
npm i node-rsa
前台部分
import NodeRSA from "node-rsa";
const publicKeyXX = { b: 512 }; // 产生的秘钥长度 必须为8的倍数
// 请求公钥API
function getPublicKeyApi(BASE_URL) {
let getPublicKeyAjax = new Promise((resolve) => {
$.ajax({
url: BASE_URL + "/get/PublicKey",
type: "GET",
success: function (result) {
resolve(result.data);
},
error: function () {},
});
});
return getPublicKeyAjax;
}
// 获取公钥
function getPublicKey() {
let publicKey_ = new Promise((resolve) => {
getPublicKeyApi().then((PubKey) => {
// PubKey 为后台返回的公钥
resolve(PubKey);
});
});
return publicKey_;
}
// 生成密文
var encryptStr = async function (password) {
let clientKey = new NodeRSA(publicKeyXX);
var pubKey = await getPublicKey(); //从服务端接收到的公钥
clientKey.importKey(pubKey);
let encrypted = clientKey.encrypt(password, "base64");
return encrypted;
};
export { encryptStr, getPublicKey };
node后台
const NodeRSA = require('node-rsa');
// 初始化时直接创建公钥、私钥
function initNodeRSA() {
let key = new NodeRSA({ b: 512 });
let publicDer = key.exportKey("pkcs8-public");
let privateDer = key.exportKey("pkcs8-private");
global.publicCacheDer = publicDer
global.privateCacheDer = privateDer
}
initNodeRSA()
// 解密 密文
function decryptPassWord (pwd) {
let key = new NodeRSA({ b: 512 });
let privateDer_ = global.privateCacheDer; //从缓存读取私钥
if (!privateDer_) {
console.log("获取RSA私钥失败!!");
return null;
}
key.importKey(privateDer_);
if (!key.isPrivate()) {
//验证私钥是否正确
console.log("导入RSA私钥失败!!");
return null;
}
let password = null;
try{
password = key.decrypt(pwd, "utf8"); // 注意此处为 utf8 才能得到用户密码,并不是前台的base64
} catch (e) {
console.log("密码解密出错 ");
console.log('e: ', e);
}
return password; //解密
};
说明
注意:每次服务重启后公钥会改变,所以前台每次都请求一下,也可以按照自己需求将公钥存在localStorage 每次从缓存中读取,避免频繁请求公钥,当解密失败的时候 再去请求一下公钥即可。