Node.js中使用node-rsa加密/解密

前言

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值