当前位置: 首页 > news >正文

NESTJS - RSA加解密

1、生成密钥(2048位)

openssl genrsa -out private_key.pem 2048

2、从密钥中提取公钥

openssl rsa -in private_key.pem -pubout -out public_key.pem

密钥存放在服务端,公钥存在放在客户端,通过公钥进行加密,私钥进行解密

注:RSA加密有长度限制,,所以一般的做法为:
1、每次发起请求时
随机生成临时32字节的密钥
2、通过RSA对32字节的密钥进行加密
3、将
32字节的密钥当做AES的密钥,对请求体进行AES加密
4、将
RSA加密后的32字节的密钥 AES加密后的请求体 发送给服务端
5、服务端拿到后先将
RSA加密后的32字节的密钥 进行解密,得到AES加密的密钥,然后使用密钥对请求体进行AES解密,就可以拿到最终的请求体了

3、前端使用RSA公钥对数据进行加密 (pnpm i node-forge)

import * as forge from 'node-forge';// 使用 RSA 公钥 加密  参数为 要加密的数据以及公钥(public_key.pem的值)
export const rsaEncrypt = (data: string, publicKeyPem: string): string => {// 1. 将字符串转换为字节const bytes = forge.util.encodeUtf8(data);// 2. 解析 PEM 公钥const publicKey = forge.pki.publicKeyFromPem(publicKeyPem);// 3. 使用 RSA-OAEP + SHA-256 加密const encryptedBytes = publicKey.encrypt(bytes, 'RSA-OAEP', {md: forge.md.sha256.create(),     // OAEP 主哈希mgf1: forge.md.sha1.create(),   // MGF1 哈希(必须指定)});// 4. 转为 base64 字符串(便于 JSON 传输)const encryptedBase64 = forge.util.encode64(encryptedBytes);return encryptedBase64;
};

4、服务端RAS解密 

import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import * as crypto from 'crypto';
import * as fs from 'fs';
import path from "path";@Injectable()
export class RsaService {private privateKey: string;constructor(private readonly configService: ConfigService) {// 私钥的内容this.privateKey = fs.readFileSync(path.join(__dirname, "../../../", this.configService.get("rsaKeys.privateKey")!), 'utf-8');}// 返回解密数据decryptAesKey(encryptedKey: string) {const buffer = Buffer.from(encryptedKey, 'base64');const decrypted = crypto.privateDecrypt({key: this.privateKey,padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,oaepHash: 'sha256',},buffer,);return decrypted.toString('utf-8'); //返回解密数据}}

5、导入服务 直接使用即可

import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response, NextFunction } from "express";
import { WinstonService } from "./winston-service";
import { ConfigService } from "@nestjs/config";
import { AesService } from "../crypto/aes-service";
import { RsaService } from "../crypto/rsa-service";// 请求日志中间件。进行解密与记录日志
@Injectable()
export class RequestLoggerMiddleware implements NestMiddleware {constructor(private readonly winstonService: WinstonService,private readonly configService: ConfigService,private readonly aesService: AesService,private readonly rsaService: RsaService) {}use(req: Request, res: Response, next: NextFunction) {if (req.method == "POST") {const aesKey = this.rsaService.decrypt(req.body.id);const decryptedBody = this.aesService.decrypt(req.body.info, aesKey);req.body = JSON.parse(decryptedBody);}if (this.configService.get("env") != "development") {this.winstonService.log('winstonRoute', {url: req.originalUrl,query: req.query,body: req.body,method: req.method,ip: req.ip,token: req.headers.authorization})}next();}
}

我这边是前端将 RSA加密后的32字节的密钥 作为id
AES加密后的请求体            作为info 传递过来的,所以通过

this.rsaService.decrypt(req.body.id) 解密,得到AES的密钥,
然后再将info和密钥传递给
this.aesService.decrypt(req.body.info, aesKey)进行取得body体

http://www.dtcms.com/a/606688.html

相关文章:

  • 自己服务器可以做网站如何做家教网站赚钱
  • 开发外贸网站开发企业官网的建设
  • 一、Rabbit MQ 初级
  • 单位网站建设费用神马搜索推广
  • 【MySQL】MySQL内置函数--日期函数字符串函数数学函数其他相关函数
  • 数据结构 力扣 练习
  • 2018年网站建设发言凯里网站开发
  • XML 和 JSON -----几种重要模式
  • 【读论文】基于LLM增强的全双工对话
  • 怎么做网站不被发现崇明网站开发
  • Java后端常用技术选型 |(二)工具类篇
  • FPGA教程系列-Vivado IP核BMG核
  • 【1.11】基于FPGA的costas环开发5——环路滤波器模块开发
  • 济南行知网站建设南京淄博网站建设工作室
  • 网站木马 代码网站建设新手
  • 汕头市国外网站建设公司百度关键词优化查询
  • 业务流低代码平台:从理念到实战
  • DebugView 学习笔记(8.9):什么是调试输出?为什么它是现场排障的“读心术”
  • RSS 语法:全面解析与优化指南
  • php能做手机网站吗口碑营销成功的案例
  • 【每日一面】BOM 是什么
  • 稀土抑烟剂在透明膜上的应用:安全与环保的双重保障
  • 郑州网站建设中心wordpress2016
  • 最新企业网站制作短链接网站
  • 建设部标准规范网站网页设计与制作教程考试试卷
  • 基于Python+OpenCV实现双目立体视觉的图像匹配与测距
  • duckdb使用详解
  • 【愚公系列】《MCP协议与AI Agent开发》010-MCP协议标准与规范体系(协议消息结构设计)
  • 3、日常脚本:文件去重(删除重复文件)
  • 物流公司网站方案wordpress搭建系统