前言
RSA算法是一种非对称加密算法,与对称加密算法不同的是,RSA算法有两个不同的密钥,一个是公钥,一个是私钥。本文介绍使用第三方库node-rsa
来实现RSA的加密、解密。
用法1:公钥加密=>私钥解密
用法2:私钥加密=>公钥解密
私钥可以推出公钥,公钥不能推出私钥,为了安全不要公开私钥。
安装
npm i --save node-rsa
公钥加密
// import NodeRSA from 'node-rsa';
const NodeRSA = require('node-rsa');
// 公钥key
const publicKey = `-----BEGIN PUBLIC KEY-----公钥-----END PUBLIC KEY-----`;
// 创建 RSA 实例
const encryptor = new NodeRSA(publicKey);
encryptor.setOptions({ encryptionScheme: 'pkcs1' }); //指定加密格式 不改格式得话可能会报错
// 要加密的数据
const plaintext = 'Hello, RSA!';
// 使用公钥加密数据
const encrypted = encryptor.encrypt(plaintext, 'base64');
公钥解密
// import NodeRSA from 'node-rsa';
const NodeRSA = require('node-rsa');
// 公钥key
const publicKey = `-----BEGIN PUBLIC KEY-----公钥-----END PUBLIC KEY-----`;
// 创建 RSA 实例
const decryptor = new NodeRSA(publicKey);
decryptor.setOptions({ encryptionScheme: 'pkcs1' }); //指定加密格式 不改格式得话可能会报错
// 要解密的数据
const data= 'ySHGmybHYrINwGjputio+8D8v441pGmAICtnHm1CjYz26mQdFciFDVWFEPZL2rs03OEg/XaCk5gdEEjTxfRbRRAcvOzTC3lNIGsHIBhqB+0EZ3C5ntXCOe+74xncHWYOiIVwU9ndHfZtqTWrxTs2R+sWnN6nUQ+m+AlZpe5kxUml3eX3tnZWg2+mRNv+ZQM7uZ2ZEXi+Xbg5qrl4rJialQz7eVCnFqWt1WUzVwEWrzmuLydyp4cRKwSMeNOOGtJHByTzynWOIWBLkiH1vyOutihNu8bb4g6KP072VbqZASQUe752Yz1XrBVJHDJsyN3x1vebn0XU6uRepf0R8OuOXA==';
// 使用公钥解密数据
const decrypted= decryptor.decryptPublic(data, "utf8");
私钥加密
// import NodeRSA from 'node-rsa';
const NodeRSA = require('node-rsa');
// 私钥Key
const privateKey = `-----BEGIN PRIVATE KEY-----私钥-----END PRIVATE KEY-----`;
// 创建 RSA 实例
const encryptor = new NodeRSA(privateKey);
encryptor.setOptions({ encryptionScheme: 'pkcs1' }); //指定加密格式 不改格式得话可能会报错
// 要加密的数据
const plaintext = 'Hello, RSA!';
// 使用私钥加密数据
const encrypted = encryptor.encryptPrivate(plaintext, 'base64');
私钥解密
// import NodeRSA from 'node-rsa';
const NodeRSA = require('node-rsa');
// 私钥Key
const privateKey = `-----BEGIN PRIVATE KEY-----私钥-----END PRIVATE KEY-----`;
// 创建 RSA 实例
const decryptor = new NodeRSA(privateKey);
decryptor.setOptions({ encryptionScheme: 'pkcs1' }); //指定加密格式 不改格式得话可能会报错
// 要解密的数据
const data= 'ySHGmybHYrINwGjputio+8D8v441pGmAICtnHm1CjYz26mQdFciFDVWFEPZL2rs03OEg/XaCk5gdEEjTxfRbRRAcvOzTC3lNIGsHIBhqB+0EZ3C5ntXCOe+74xncHWYOiIVwU9ndHfZtqTWrxTs2R+sWnN6nUQ+m+AlZpe5kxUml3eX3tnZWg2+mRNv+ZQM7uZ2ZEXi+Xbg5qrl4rJialQz7eVCnFqWt1WUzVwEWrzmuLydyp4cRKwSMeNOOGtJHByTzynWOIWBLkiH1vyOutihNu8bb4g6KP072VbqZASQUe752Yz1XrBVJHDJsyN3x1vebn0XU6uRepf0R8OuOXA==';
// 使用私钥解密数据
const decrypted= decryptor.decrypt(data, "utf8");
分段加密
import NodeRSA from 'node-rsa';
import Base64 from 'base64-js';
// 分段加密
function segmentedEncryption(data) {
// 公钥key
const publicKey = `-----BEGIN PUBLIC KEY-----公钥-----END PUBLIC KEY-----`;
// 创建 RSA 实例
const encryptor = new NodeRSA(publicKey);
encryptor.setOptions({ encryptionScheme: 'pkcs1' }); //指定加密格式 不改格式得话可能会报错
// 把加密字符串进行分段
const list = getSectionStrList(data);
let bufferArr = new Uint8Array(list.length * 256);
for (let i = 0; i < list.length; i++) {
// 逐段进行加密写入btye数组对应位置
let arrayTwo = encryptor.encrypt(list[i], 'buffer');
bufferArr.set(arrayTwo, i * 256);
}
// btye数组转base64
return arrayBufferToBase64(bufferArr);
}
// 最大明文加密长度(单位:字节)
const MAX_ENCRYPT_BLOCK = 245;
// 字符串分段
function getSectionStrList(string) {
let list = [];
const len = string.length;
// 字节数
let byteNum = 0;
// 字符串开始截取位置
let startNum = 0;
for (let i = 0; i < len; i++) {
let c = string.charCodeAt(i);
// 1.累计每个字符串所占的byte长度
if (c >= 0x010000 && c <= 0x10FFFF) {
byteNum += 4;
} else if (c >= 0x000800 && c <= 0x00FFFF) {
byteNum += 3;
} else if (c >= 0x000080 && c <= 0x0007FF) {
byteNum += 2;
} else {
byteNum += 1;
}
// 2.byte长度累计到最大明文加密长度-3,则开始截取字符串进行加密
if (byteNum >= (MAX_ENCRYPT_BLOCK - 3) || i == len - 1) {
let endNum = i + 1;
list.push(string.substring(startNum, endNum));
// byte长度清零再重新累计截取字符串
byteNum = 0;
startNum = endNum;
}
}
return list;
}
// btye数组转base64
function arrayBufferToBase64(buffer) {
const uint8Array = new Uint8Array(buffer);
const base64Data = Base64.fromByteArray(uint8Array);
return base64Data;
}