当前位置: 首页 > 工具软件 > node-ab > 使用案例 >

RSA加密简单理解,node-rsa使用记录

贝洲
2023-12-01

RSA

非对称加密,一般由发送方(客户端)和接收方(服务端)各持有一对公钥和私钥。

私钥可以推出公钥,公钥不能推出私钥。

数据交换的过程中,双方交换自己的公钥。各自私钥不公开。

发送时使用对方的公钥进行加密。接收对方发来的密文时,使用自己私钥进行解密

发送方使用私钥将信息进行加签(签名),将密文与签名作为参数发起请求。

接收方用自己私钥解密得到的明文,请求方公钥,接收的签名,进行验签(签名验证)。

RSA签名和验签的作用

为了增强数据交换的安全性

假设不进行签名和验签:

  • 发送方(客户端)的请求,可能被第三方拦截(中间人攻击)。
  • 中间人在拦截发送方请求(不知道拦截的请求参数明文)
  • 由于接收方(服务端)的公钥是公开的,中间人可以使用公钥对参数加密,替换拦截到的参数密文,发送给原接收方(服务端)。(当然这个发送的参数格式是什么,中间人知道不知道就另寻它路了)
  • 这导致接收方(服务端)无法判断得到的请求是否是可信的客户端发送的。(因为请求头什么的都是对的,参数被中间人替换了)

发送方如果增加签名可以不用加密请求参数,但第三方拦截后能看到请求参数的明文(参数格式和内容被公开)。

安全性的前提是私钥没有泄露,私钥若被攻击者获取了,那么签名也可以伪造了。

node-rsa例子

const NodeRSA= require('node-rsa');
const publicKey =`
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAISIIx8u/n7M6GyGoXIotkDZKfDk28JJ
3jDhhhFm2i8+2h5NJqmgYIZIsGR4TdeD/Uti0UYFfpdVAsK4/fgyGqsCAwEAAQ==
-----END PUBLIC KEY-----
`;
const privateKey = `
-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBAISIIx8u/n7M6GyGoXIotkDZKfDk28JJ3jDhhhFm2i8+2h5NJqmg
YIZIsGR4TdeD/Uti0UYFfpdVAsK4/fgyGqsCAwEAAQJAHtZSXcIggz6IYiAdVqO0
bHhbMur9W0K2yWbgPBJTeCRxAdsx2ZJK45WfgOn+vCuuXQKNrADk84eCGyg/32AB
0QIhALlhkxdzAvUg4Q1gzn6n6nRI3C2jFPB6XOd64DMv05KpAiEAtwStPQPP5Kyx
3yxmPlprPeOJZdSfYs9RJ/pdQ/+NqzMCIQCCYYL/cg95chd2vkhdQiIeiQP6QQHA
JH9k+sHmnlOSiQIgHn1S9wU5jxkOEOXuqpiZoRfU/ffsDaQIGybkfr2GNm0CIQCK
TUs08mJG+BUvmyYe6YgY5MHuNoKx4ewXh/P0uaxPHw==
-----END RSA PRIVATE KEY-----
`;

const key = new NodeRSA({b:512});//传入{b:512} 生成512位秘钥。也可以指定publicKey /privateKey 字符串
// 加密
let encrypted = key.encrypt('你的行为和表现还是让我无法完全相信你放下了','base64');
console.log(encrypted); // VtBuzrpbcxg/F6UNYwIeN6iAwGEFabwvxGypQ3zvoH+6xJjNdnIllOf7BDpgPtNfhAQpiynwWdYEpc7ncOV4zU6/UOnNsArKITbfwYm3x42rqC0RgTtvrRSy5LAEPPjbYDgCZVqMF2vBJJTHdZkGQr6hmLsL4lMVOCunaoiLhPckNo5fih94WK/31FzpgSR5Bzrh02w4P7EQAt9+5MyDucjFLcb9VQLsfdXQtyiS+2CSVpVbVK7OnSaQ4GiK+uV9 
// 解密
let decrypted = key.decrypt(encrypted,'utf8');
console.log(decrypted);

rsa私钥可以推出公钥,公钥不能推出私钥。

console.log(new NodeRSA(privateKey).exportKey('public'));
console.log(new NodeRSA(publicKey).exportKey('private')); // 报错 not privateKey

客户端

let message = '你的行为和表现还是让我无法完全相信你放下了';
// 服务端公钥加密
let encryptedText = new NodeRSA(publicKey).encrypt(message, 'base64'); 
console.log('密文:', encryptedText);
// 使用客户端私钥加签
let signature = new NodeRSA(privateKey).sign(Buffer.from(message), 'hex'); 
console.log('签名:', signature);

服务端

// 服务端接收的密文
let encryptedText = 'H1WkC6vd2+mNe0RyDXwJex4urWHyWTg4QFJoDWF9uqiWCoUNdLE1MGNaWYsPzSd7bMnq2McwRFKImvvX49l8MWn8psd0BztrMkRZYYNAkHaKUZ/VMEn+d0h7k1nKPS8k36KZmOhwoOubzMjdN84TUVzOIjs59gJ99xJa9T0pGsNtiK2XJ/+XsUjnE37ZQo7NwOlZieZKXn4Muflm2pTrLMa17XqJhIvFgJm0iRX/aiUuDDL+g0og/a21Yl/T3qAr';
// 服务端私钥解密
let decryptedText = new NodeRSA(privateKey).decrypt(encryptedText, 'utf8');
console.log('解密:', decryptedText);
// 客户端公钥验签
let verify = new NodeRSA(publicKey).verify(Buffer.from(decryptedText), signature, 'utf-8', 'hex');
console.log('验证签名', verify);

 

 类似资料: