nodejs-使用node-rsa数字签名/隐私信息加密解密
加密解密:公钥加密,私钥解密
1.sender生成密钥对:私钥A,公钥A,将公钥A给接收者receiver
2.receiver生成密钥对:私钥B,公钥B,将公钥B给sender
3.sender持有:私钥A,公钥B
4.receiver持有:私钥B,公钥A
5.发送过程:【私钥保留在自己手中,只有自己能够解密,保证了数据的安全性】
1.sender使用公钥B加密数据发送给receiver
2.receiver使用私钥B解密数据并使用
3.receiver使用公钥A加密数据发送给sender
4.sender使用私钥A解密数据并使用
数字签名:私钥签名,公钥验签
1.数据发送者,对发送的部分信息【摘要】进行加签
2.数据接收者,对收到的数据,要根据【摘要信息】+【签名信息】取验证签名,然后才能使用数据
3.签名优缺点:
1.保证数据发送者身份
2.保证数据不会被篡改
3.不能保证数据内容不被他人获得
1.生成密钥对,可保存在配置文件中:generateKeyPair.js
const NodeRSA = require('node-rsa');
const pkcsSize = 512;
//暂存位置:可将生成好的密钥对保存在配置文件中
const conf = {
"namePri": "pkcs8-yueke",
"privatePem": "-----BEGIN PRIVATE KEY-----\nMIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA4SlLE/bIChwOFf2b\nWKpwwNshKRFpXcGi3Z9LURJ5ns8fjRNjQQBV2FRkHH7Uo+lenDDk3nkSXGtWQRg/\n9c1tAQIDAQABAkB/gNq7G2x8DRcM7OgjdaEUFQLaNrnsFdMcnTARYNzuSFu8HwFS\nwc4JGdDRVqG+x6uOg3h7tnTWj/2hYVsJiLVhAiEA/pKCCwVuSlDOzH+WyajcRCzh\n8sPIGZsvh1S8Ek9GbhsCIQDibI9D6afIPVrr6avtCI/DehN2xeFdUjmETfz0danT\nEwIhAOBCJicZWKhE+Xgy6Z2qkKfKNh2LFQphqAP6xFcI2Q2DAiBnEthdKB7TDus2\n/dbgPseDSy1VIlunaej5C6+dcXrvtQIgbdySI8DKHQYYZhUUjzIvTlcrcg7Eju4l\nfDBT+3LJ8K8=\n-----END PRIVATE KEY-----"
}
;
/**
* 生成密钥对
* 传入公司name:www.yushang
* @param name:指定格式 pkcs8
*
*/
function generateKeyPair(name, namePub, namePri) {
// 1.创建RSA对象,并指定 秘钥长度
let key = new NodeRSA({b: pkcsSize});
key.setOptions({encryptionScheme: 'pkcs1'});//指定加密格式
// 2.生成 公钥私钥,使用 pkcs8标准,pem格式
namePub = name + '-' + namePub;
namePri = name + '-' + namePri;
let publicPem = key.exportKey(namePub);//制定输出格式
let privatePem = key.exportKey(namePri);
console.log(namePub + '公钥:\n', publicPem);
console.log(namePri + '私钥:\n', privatePem);
return {
namePub: namePub,
namePri: namePri,
publicPem: publicPem,
privatePem: privatePem
};
}
/**
* 生成公私钥作为配置文件在顶部,然后注释以下代码,导出配置
* @type {{namePub: *, publicPem: *, privatePem: *, namePri: *}}
*/
// let generateKeyPair1 = generateKeyPair('pkcs8', 'miaowenjuan', 'yueke');
// console.error(generateKeyPair1);
exports.signConf = conf;
exports.generateKeyPair = generateKeyPair;
2. 数据发送者:发送数据-私钥加签;接收数据-私钥解密 dataSign.js
const NodeRSA = require('node-rsa');
const BASE64 = 'base64';
const pkcsSize = 512;
const signConf = require('./generateKeyPair').signConf;
/**
* 私钥数据签名
* @param str
*/
function dataPrivateSign(str, name, pri) {
let privateKey = new NodeRSA({b: pkcsSize});
// 2.导入 私钥,并指定使用 pkcs标准,pem格式
privateKey.importKey(pri, name);
let signedData = privateKey.sign(Buffer.from(str), BASE64, BASE64).toString(BASE64);
// let signedData = privateKey.encryptPrivate(str, BASE64, UTF8);
console.log('\n使用私钥签名:', signedData);
return signedData;
}
/**
* 对外暴露加签
* @param str
* @returns {string}
*/
function exportDataPrivateSign(str) {
return dataPrivateSign(str, signConf.namePri, signConf.privatePem);
}
// 私钥解密
function decrypt(data,privateKey) {
const nodersa = new NodeRSA(privateKey);
const decrypted = nodersa.decrypt(data, 'utf8');
return decrypted;
}
exports.exportDataPrivateSign = exportDataPrivateSign;
exports.dataPrivateSign = dataPrivateSign;
exports.decrypt = decrypt;
3.数据接收方:接收数据-公钥验签;发送数据-公钥加密 dataSignVerify.js
const NodeRSA = require('node-rsa');
const BASE64 = 'base64';
const pkcsSize = 512;
const signConf = require('./generateKeyPair').signConf;
/**
* 公钥验签
* @param str
*/
function dataPubVerifySign(str, rsaStr, name, pub) {
// 1.创建RSA对象,并指定 秘钥长度
var publicKey = new NodeRSA({b: pkcsSize});
// 2.导入 公钥,并指定使用 pkcs标准,pem格式
publicKey.importKey(pub, name);
let result = publicKey.verify(Buffer.from(str), rsaStr, BASE64, BASE64);
console.log('\n验签:\n', result);
return result;
}
// 公钥加密
function encrypt(data,publicKey) {
const nodersa = new NodeRSA(publicKey);
const encrypted = nodersa.encrypt(data, 'base64');
return encrypted;
}
/**
* 对外暴露验签
* @param str
* @returns {string}
*/
function ExportDataPubVerifySign(str,rasStr) {
return dataPubVerifySign(str, rasStr, signConf.namePub, signConf.publicPem);
}
exports.ExportDataPubVerifySign = ExportDataPubVerifySign;
exports.dataPubVerifySign = dataPubVerifySign;
exports.encrypt = encrypt;
4.测试记录test.js
let dataSign = require('./dataSign');
let dataSignVerify = require('./dataSignVerify');
/**生成密钥对*************************************************************************/
//第一个参数:指定加密格式 第二个参数接收者公司名称或其自定义名称 第三个参数发送者公司名称或其自定义名称
let generateKeyPair = require('./generateKeyPair').generateKeyPair('pkcs8', 'receiver', 'sender');
let namePub = generateKeyPair.namePub;
let namePri = generateKeyPair.namePri;
let publicPem = generateKeyPair.publicPem;
let privatePem = generateKeyPair.privatePem;
/**生成密钥对*************************************************************************/
/**私钥加签***************************************************************************/
//sender发送数据加签:一般进行信息摘要后加签,防止加密信息过大,损耗性能
//此处的str可以是uri上的路径参数,也可以是请求体中的一部分数据
//let uri = 'http://www.baidu.com?name=li&age=18&pwd=111111';
//由于以上示例路径参数较少,可以选择对参数全部加签,也可进行摘要加签,选择摘要要告知对方摘要信息是哪些
let str = 'name=li生活&age=18&pwd=111111';
let sign = dataSign.dataPrivateSign(str, namePri, privatePem);
//生成sign连接参数,以下为发送的实际参数
let strr = str + "&sign=" + sign;
console.error("最后发送参数:" + strr);
/**私钥加签***********************![在这里插入图片描述](https://img-blog.csdnimg.cn/20191106105756530.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTc4NDY0Mg==,size_16,color_FFFFFF,t_70)****************************************************/
/**公钥验签***************************************************************************/
// 接收到的参数:strr
// 取出签名:sign和摘要数据str
let dataPubVerifySign = dataSignVerify.dataPubVerifySign(str, sign, namePub, publicPem);
console.error("验签结果:" + dataPubVerifySign);
/**公钥验签***************************************************************************/
/**公钥加密,私钥解密***************************************************************************/
let encrypt = dataSignVerify.encrypt(str, publicPem);
let decrypt = dataSign.decrypt(encrypt, privatePem);
console.error(encrypt);
console.error(decrypt);
/**公钥加密,私钥解密***************************************************************************/