【nodejs】使用node-rsa数字签名/隐私信息加密解密

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);
/**公钥加密,私钥解密***************************************************************************/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皇夜_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值