vue通信加密解密完整方案实现
前后端加密解密完整方案实现
基于Vue3 + Pinia + Axios的前后端通信加密解密方案。该方案采用RSA+AES混合加密机制,确保数据传输的安全性。
文章目录
- 前后端加密解密完整方案实现
- 前言
- 一、加密策略
- 二、加密流程
- 1. 加密存储 (crypto.js)
- 2.Axios拦截器配置 (request.js)
- 三、使用方法
- 1. 环境配置
- 2. 在组件中使用
- 四、安全性考虑
- 1. 密钥管理
- 2. 加密算法
- 3. 传输安全
- 4.还能进行的性能优化:
- 五、部署建议
- 1.生产环境配置
- 2.性能监控
- 3.安全审计
- 总结
前言
- 前端框架: Vue3 + Pinia
- 加密库: crypto-js + jsencrypt
- HTTP客户端: Axios
一、加密策略
采用混合加密机制:
- AES加密: 用于加密大量业务数据(对称加密,效率高)
- RSA加密: 用于加密AES密钥(非对称加密,安全性高)
二、加密流程

1. 加密存储 (crypto.js)
代码如下(示例):
import { defineStore } from "pinia";
import CryptoJS from "crypto-js";
import JSEncrypt from "jsencrypt/bin/jsencrypt.min";export default defineStore("cryptoStore", {state: () => ({backendPublicKey: import.meta.env.VITE_APP_PUBLIC_KEY, // 后端rsa公钥frontendKeyAndIvArray: [], // 前端AES密钥与IV组合}),actions: {/*** 生成前端AES密钥和IV*/generateFrontendKey(url) {// 生成32字节(256位)随机密钥const _AesKey = CryptoJS.lib.WordArray.random(32);const frontendKey = CryptoJS.enc.Base64.stringify(_AesKey);// 生成16字节(128位)随机IVconst _iv = CryptoJS.lib.WordArray.random(16);const frontendIv = CryptoJS.enc.Base64.stringify(_iv);// 存储密钥对this.frontendKeyAndIvArray.push({url,key: frontendKey,iv: frontendIv,});return { key: frontendKey, iv: frontendIv };},/*** 准备加密载荷*/async prepareEncryptedPayload(url, datajson) {// 生成密钥和IVconst frontendKeyIv = this.generateFrontendKey(url);// 序列化数据const text = typeof datajson === 'string' ? datajson : JSON.stringify(datajson);// AES-CBC加密const dataCipher = CryptoJS.AES.encrypt(text,CryptoJS.enc.Base64.parse(frontendKeyIv.key),{iv: CryptoJS.enc.Base64.parse(frontendKeyIv.iv),mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7,}).toString();// RSA加密AES密钥const rsa = new JSEncrypt();rsa.setPublicKey(this.backendPublicKey);const encryptKey = rsa.encrypt(frontendKeyIv.key);if (!encryptKey) throw new Error("RSA公钥加密失败");return {encryptKey,iv: frontendKeyIv.iv,data: dataCipher,};},/*** 解密并销毁密钥*/decryptAndDestroy(requestConfig, ciphertext) {if (!ciphertext) return null;// 查找对应的密钥和IVconst frontendKeyIv = this.frontendKeyAndIvArray.find((item) => item.iv === requestConfig.headers["X-Encrypt-Iv"]);if (!frontendKeyIv) {throw new Error("前端密钥/IV不存在");}// AES解密const bytes = CryptoJS.AES.decrypt(ciphertext,CryptoJS.enc.Base64.parse(frontendKeyIv.key),{iv: CryptoJS.enc.Base64.parse(frontendKeyIv.iv),mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7,});const plain = bytes.toString(CryptoJS.enc.Utf8);// 销毁密钥this.destroyCurrentKeyAndIv(frontendKeyIv.iv);// 尝试解析JSONtry {return JSON.parse(plain);} catch (e) {return plain;}},/*** 销毁指定密钥*/destroyCurrentKeyAndIv(iv) {this.frontendKeyAndIvArray = this.frontendKeyAndIvArray.filter((item) => item.iv !== iv);},},
});
2.Axios拦截器配置 (request.js)
代码如下(示例):
import axios from "axios";
import useCryptoStore from "@/store/modules/crypto";// 创建axios实例
const service = axios.create({baseURL: import.meta.env.VITE_APP_BASE_API,timeout: 30 * 1000,
});// 请求拦截器
service.interceptors.request.use(async (config) => {const cryptoStore = useCryptoStore();// 是否需要加密(通过请求头控制)const notCrypto = (config.headers || {}).notCrypto === false;if (!notCrypto) {// 加密请求数据const crypto = await cryptoStore.prepareEncryptedPayload(config.url, config.data);// 设置加密相关请求头config.headers["X-Encrypt-Key"] = crypto.encryptKey;config.headers["X-Encrypt-Iv"] = crypto.iv;config.data = { data: crypto.data };}return config;},(error) => {return Promise.reject(error);}
);// 响应拦截器
service.interceptors.response.use((res) => {const code = res.data.code || 200;// 二进制数据直接返回if (res.request.responseType === "blob" || res.request.responseType === "arraybuffer") {return res.data;}// 错误处理if (code !== 200) {// ... 错误处理逻辑return Promise.reject(new Error(msg));}// 解密响应数据const cryptoStore = useCryptoStore();let decryptedData = null;if (res.data.data || res.data.rows) {decryptedData = cryptoStore.decryptAndDestroy(res.config,res.data.data ?? res.data.rows);// 更新响应数据 根据实际情况进行调整if (res.data.data !== undefined) res.data.data = decryptedData;if (res.data.rows !== undefined) res.data.rows = decryptedData;}return Promise.resolve(res.data);},(error) => {// ... 错误处理return Promise.reject(error);}
);export default service;
三、使用方法
1. 环境配置
# .env.development
VITE_APP_PUBLIC_KEY=后端RSA公钥
VITE_APP_BASE_API=http://localhost:8080/api
VITE_APP_ENV=development
2. 在组件中使用
import axios from '@/utils/request';// 发送加密请求
const sendEncryptedRequest = async () => {try {const response = await axios.post('/user/info', {username: 'test',password: '123456'});console.log('解密后的数据:', response);} catch (error) {console.error('请求失败:', error);}
};// 跳过加密(通过请求头控制)
const sendNormalRequest = async () => {const response = await axios.post('/public/info', {data: 'public data'}, {headers: {notCrypto: true // 跳过加密}});
};
四、安全性考虑
1. 密钥管理
- ✅ 每次请求生成独立的AES密钥和IV
- ✅ 请求完成后立即销毁前端密钥
- ✅ 使用RSA公钥加密传输AES密钥
2. 加密算法
- ✅ AES-256-CBC:高强度对称加密
- ✅ RSA:非对称加密保护密钥传输
- ✅ PKCS7填充:标准填充方式
3. 传输安全
- ✅ HTTPS传输(生产环境)
- ✅ 自定义加密头标识
- ✅ 防重放攻击(时间戳验证)
4.还能进行的性能优化:
1. 加密性能- 使用Web Workers进行大量数据加密(可选)
- 异步加密避免阻塞主线程2. 内存管理- 及时清理敏感数据
- 使用Array.filter销毁密钥引用3. 网络优化- 支持请求缓存配置
- 二进制数据跳过加密处理
五、部署建议
1.生产环境配置
# .env.production
VITE_APP_PUBLIC_KEY=生产环境RSA公钥
VITE_APP_BASE_API=https://api.production.com
VITE_APP_ENV=production
2.性能监控
// 添加性能监控
const startTime = performance.now();
// ... 加密操作
const encryptTime = performance.now() - startTime;
console.log(`加密耗时: ${encryptTime}ms`);
3.安全审计
- 定期检查加密算法安全性
- 更新密钥对(建议每3-6个月)
- 监控异常请求模式
总结
本方案提供了一个完整的前后端通信加密解决方案,具有以下特点:
- ✅ 安全性高:RSA+AES混合加密,确保数据传输安全
- ✅ 性能优秀:AES加密大量数据,RSA只加密密钥
- ✅易于集成:基于Axios拦截器,对业务代码无侵入
- ✅ 灵活配置:支持跳过加密、自定义加密策略
- ✅内存安全:及时销毁敏感数据,防止内存泄漏通过这套方案,可以有效保护前后端通信数据,防止中间人攻击、数据泄露等安全风险。
