# 接口加密功能改造日志 ## 📅 改造日期 2025-12-10 ## 🎯 改造目标 参考 `stm32-iot-vben5` 项目的加密实现,为 UniApp 项目添加接口加密功能,支持 RSA + AES 混合加密方案。 --- ## 📝 改造内容 ### 1. 新增文件 #### ✅ `utils/crypto.js` **用途:** 加密工具类 **功能:** - `randomStr(length)` - 生成随机字符串 - `encodeBase64(str)` - Base64 编码 - `decodeBase64(str)` - Base64 解码 - `RsaEncryption` - RSA 加密/解密类 - `AesEncryption` - AES 加密/解密类 **依赖:** - `crypto-js` - AES 加密 - `jsencrypt` - RSA 加密 #### ✅ 文档文件 | 文件名 | 用途 | |--------|------| | `ENCRYPT_GUIDE.md` | 完整的加密功能使用指南 | | `INSTALL_DEPENDENCIES.md` | 依赖安装说明 | | `QUICK_START.md` | 5分钟快速开始指南 | | `api/login.encrypt.example.js` | 接口加密示例代码 | | `CHANGELOG_ENCRYPTION.md` | 本文件 | ### 2. 修改文件 #### ✅ `config.js` **新增配置项:** ```javascript { clientId: 'e5cd7e4891bf95d1d19206ce24a7b32e', // 客户端ID enableEncrypt: false, // 全局加密开关 rsaPublicKey: '...', // RSA公钥 rsaPrivateKey: '' // RSA私钥 } ``` #### ✅ `utils/request.js` **主要改动:** 1. **导入加密工具** ```javascript import { RsaEncryption, AesEncryption, randomStr, encodeBase64, decodeBase64 } from '@/utils/crypto' ``` 2. **初始化加密实例** ```javascript const asymmetricEncryption = new RsaEncryption({ publicKey: rsaPublicKey, privateKey: rsaPrivateKey }) const symmetricEncryption = new AesEncryption() ``` 3. **请求拦截器增强** - 添加 `ClientID` 请求头 - 检测 `encrypt: true` 配置 - 生成随机 AES 密钥 - 使用 RSA 加密 AES 密钥 - 使用 AES 加密请求数据 4. **响应拦截器增强** - 检测响应头 `encrypt-key` - 使用 RSA 解密 AES 密钥 - 使用 AES 解密响应数据 - 异常处理和错误提示 --- ## 🔄 加密流程 ### 请求加密流程 ``` 1. 判断是否需要加密 ↓ 2. 生成 32 位随机 AES 密钥 ↓ 3. Base64 编码 AES 密钥 ↓ 4. RSA 加密 Base64 密钥 → 请求头 encrypt-key ↓ 5. AES 加密请求数据 → 请求体 ↓ 6. 发送请求 ``` ### 响应解密流程 ``` 1. 检查响应头 encrypt-key ↓ 2. RSA 解密得到 Base64 密钥 ↓ 3. Base64 解码得到 AES 密钥 ↓ 4. AES 解密响应数据 ↓ 5. JSON 解析返回数据 ``` --- ## 🆚 对比参考项目 ### 相同点 | 特性 | stm32-iot-vben5 | stm32-iot-app | |------|-----------------|---------------| | 加密算法 | RSA + AES | RSA + AES | | 加密开关 | enableEncrypt | enableEncrypt | | 密钥配置 | rsaPublicKey | rsaPublicKey | | 请求头 | encrypt-key | encrypt-key | | 客户端ID | ClientID | ClientID | | 加密方法 | POST/PUT | POST/PUT | ### 差异点 | 项目 | 框架 | 请求库 | 语言 | |------|------|--------|------| | stm32-iot-vben5 | Vue 3 + Vite | axios | TypeScript | | stm32-iot-app | UniApp | uni.request | JavaScript | --- ## 📦 依赖要求 ### 必需安装 ```json { "dependencies": { "crypto-js": "^4.2.0", "jsencrypt": "^3.3.2" } } ``` ### 安装命令 ```bash npm install crypto-js jsencrypt ``` --- ## 🎯 使用方式 ### 方式一:单个接口启用 ```javascript export function login(data) { return request({ url: '/login', method: 'post', data: data, encrypt: true // 启用加密 }) } ``` ### 方式二:全局启用 ```javascript // config.js export default { enableEncrypt: true, // 全局开启 // ... } // api 文件中标记需要加密的接口 export function sensitiveApi(data) { return request({ url: '/api/sensitive', method: 'post', data: data, encrypt: true // 需要加密 }) } ``` --- ## ⚠️ 注意事项 ### 1. 加密限制 - ✅ 仅支持 POST/PUT 请求 - ❌ GET/DELETE 请求不支持加密 ### 2. 配置要求 - 必须配置正确的 RSA 公钥 - 公钥必须与后端保持一致 - clientId 与后端保持一致 ### 3. 兼容性 - H5 端完全支持 ✅ - App 端完全支持 ✅ - 小程序端需测试 ⚠️ ### 4. 性能影响 - 加密操作增加约 50-100ms 延迟 - 建议仅对敏感接口启用 - 不建议对所有接口启用 --- ## 🐛 已知问题 ### 1. 小程序兼容性 **问题:** 某些小程序平台可能不支持 crypto-js/jsencrypt **解决方案:** - 使用小程序原生加密 API - 使用 uni-app 插件市场的加密插件 - 小程序端关闭加密 ### 2. 响应头大小写 **问题:** 不同平台返回的响应头可能是 `header` 或 `headers` **解决方案:** ```javascript const encryptKey = (res.header || res.headers || {})['encrypt-key'] ``` --- ## ✅ 测试清单 ### 功能测试 - [ ] POST 请求加密成功 - [ ] PUT 请求加密成功 - [ ] GET 请求正常(不加密) - [ ] 响应解密成功 - [ ] 错误提示正常 ### 平台测试 - [ ] H5 端 - [ ] Android App - [ ] iOS App - [ ] 微信小程序 - [ ] 其他小程序 ### 异常测试 - [ ] 未安装依赖时的提示 - [ ] 公钥错误时的提示 - [ ] 后端不支持加密时的处理 - [ ] 解密失败时的处理 --- ## 📖 参考资料 ### 项目参考 - 参考项目:`stm32-iot-vben5/apps/web-antd/src/api/request.ts` - RuoYi 官方文档:http://doc.ruoyi.vip/ ### 技术文档 - UniApp 官方文档:https://uniapp.dcloud.net.cn/ - crypto-js:https://github.com/brix/crypto-js - jsencrypt:https://github.com/travist/jsencrypt --- ## 🔮 未来优化 ### 计划中 1. 支持 SM2/SM4 国密算法 2. 支持小程序原生加密方案 3. 添加自动化测试 4. 性能优化(密钥缓存) ### 待评估 1. 支持更多加密算法 2. 支持请求签名验证 3. 支持加密日志脱敏 --- ## 👨‍💻 贡献者 - 主要开发:AI Assistant - 参考项目:stm32-iot-vben5 - 技术支持:RuoYi 开源社区 --- ## 📄 许可证 本改造遵循原项目许可证。 --- **改造完成日期:** 2025-12-10 **文档版本:** 1.0.0