nest端使用 “crypto” 插件
实现加解密工具函数
// 加密
export const enCrypt = (info) => {
if (typeof info === 'object') {
info = JSON.stringify(info);
}
const cipher = createCipheriv(
'aes-256-cbc',
Buffer.from(cryptoKey),
Buffer.from(aesIv),
);
const encrypted = cipher.update(info, 'utf8', 'hex') + cipher.final('hex');
// 十六进制字符串转换为 Buffer
const buffer = Buffer.from(encrypted, 'hex');
// 将 Buffer 转换为 Base64 编码的字符串
const base64String = buffer.toString('base64');
return base64String;
};
// 解密
export const deCrypt = (info: any) => {
console.log(info, '加密');
info = info.replace(/\r\n/g, '');
if (!isHex(info)) {
const buffer = Buffer.from(info, 'base64'); // Base64 解码为 Buffer
info = buffer.toString('hex'); //buffer解析为16进制
}
console.log(info, '1');
const decipher = createDecipheriv(
'aes-256-cbc',
Buffer.from(cryptoKey),
Buffer.from(aesIv),
);
console.log(decipher, '2');
decipher.setAutoPadding(true); // 这将自动移除PKCS#7填充
console.log(decipher, '3');
const decrypted =
decipher.update(info, 'hex', 'utf8') + decipher.final('utf8');
return decrypted;
};
中间件内实现token鉴权及请求体解密:
仅实现关键代码、并未对各种情况进行处理,未写功能
export class AppMiddleware implements NestMiddleware {
@Inject(JwtService)
private jwtService: JwtService;
use(req: Request, res: Response, next: () => void) {
// console.log('开始执行中间件aaa...', req.body, req.originalUrl, req.baseUrl);
const secretData = req.body.data;
console.log(req.headers.authorization, 'shili');
const authorization = req.headers.authorization;
if (authorization) {
const authorizationRow = authorization.slice(7);
const data = this.jwtService.verify(authorizationRow);
console.log(data, 'jwt');
}
if (secretData) {
const deData = deCrypt(secretData);
console.log('解密:', deData);
req.body.data = deData;
}
next();
console.log('结束执行中间件aaa...');
}
}
login接口拿到解密后的前端传输数据,进行相关判断操作(省略)后,返回生成的token
@Injectable()
export class AppService {
@Inject(JwtService)
private jwtService: JwtService;
getHello(): string {
return 'Hello Wor12321321ld!';
}
login(dto): string {
console.log(dto, 'dto');
const data = JSON.parse(dto.data);
const token = this.jwtService.sign({
userName: data.phone,
});
console.log(token, 'zhijie');
return `bearer ${token}`;
}
}
拦截器对响应体做加密操作
import {
CallHandler,
ExecutionContext,
Injectable,
NestInterceptor,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { enCrypt } from 'src/utils/crypt';
@Injectable()
export class CryptoInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next
.handle()
.pipe(
map((data) => ({ code: 200, data: enCrypt(JSON.stringify(data)) })),
);
}
}
前端使用对应的插件实现方法即可:一般配置在request.js中用拦截器实现
import CryptoJS from 'crypto-js'
const cryptoKey = 'adjg894kjgng394uadjg894kjgng394u'
const ivStr = 'adjg894kjgng394u'
// 解密
export const decrypt = (info) => {
var key = CryptoJS.enc.Utf8.parse(cryptoKey);
let iv = CryptoJS.enc.Utf8.parse(ivStr);
var decrypt = CryptoJS.AES.decrypt(info, key, {
iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypt.toString(CryptoJS.enc.Utf8);
}
export const enCrypto = (info) => {
const encryptedContent = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(info), CryptoJS.enc.Utf8.parse(cryptoKey), {
iv: CryptoJS.enc.Utf8.parse(ivStr),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(encryptedContent)
const encStr = encryptedContent.toString()
return encStr
}