2026-04-20-10-14-09 - 安全加固:XOR→AES-GCM、API Key环境变量化、授权码SHA-256哈希、消除硬编码密钥
This commit is contained in:
42
工程分析/经验记录.md
42
工程分析/经验记录.md
@@ -28,5 +28,45 @@
|
||||
|
||||
## 历史记录
|
||||
|
||||
(以下为实际踩坑记录,按时间倒序排列)
|
||||
### [2026-04-20-10-14-09] Web Crypto API 异步性与 storage 同步接口冲突
|
||||
|
||||
### A. 具体问题
|
||||
需求要求将 `systemSettings` 的加密从 XOR 升级为 Web Crypto API AES-GCM,同时维持 `storage.get/set` 的同步调用签名。但 `crypto.subtle` 的所有加解密操作均为异步 Promise,若直接将 `storage.get/set` 改为 async,将导致 ReportEditor.tsx、Login.tsx 等数十处调用点需要同步改为 await,改动面极大且风险不可控。
|
||||
|
||||
### B. 产生问题原因
|
||||
Web Crypto API 是浏览器原生标准,设计为全异步 API,无法像 crypto-js 那样提供同步调用。而项目早期设计时 `storage` 模块全部为同步接口,未预留异步扩展点。
|
||||
|
||||
### C. 解决问题方案
|
||||
采用"启动时预解密 + 内存缓存"的折中方案:
|
||||
1. 在 `storage.ts` 中新增异步 `init()` 函数,在应用启动(`main.tsx` 中 `await storage.init()`)时预解密 `systemSettings` 到模块级内存缓存 `systemSettingsCache`。
|
||||
2. `storage.get('systemSettings')` 改为从缓存同步返回,`storage.set('systemSettings')` 改为更新缓存并触发异步持久化(不阻塞调用方)。
|
||||
3. 其他 key 的读写保持原样,完全不受影响。
|
||||
4. 该方案无需修改任何业务组件中 `storage.get('systemSettings')` 的调用方式。
|
||||
|
||||
### D. 后续如何避免问题
|
||||
- 若未来再次遇到"必须引入异步存储操作"的需求,优先评估能否用"启动预加载 + 内存缓存"模式规避接口签名变更。
|
||||
- 若必须改异步接口,应将影响范围限制在单一 key(如新增 `getAsync/setAsync`),而非全局改动 `storage.get/set`。
|
||||
- 在需求分析阶段增加"接口兼容性影响评估"子项,提前识别同步/异步冲突。
|
||||
|
||||
---
|
||||
|
||||
### [2026-04-20-10-14-09] 旧数据兼容密钥与"消除硬编码"验收标准冲突
|
||||
|
||||
### A. 具体问题
|
||||
安全加固的验收标准要求"构建产物中不再出现任何硬编码密钥字符串"。但实现 AES-GCM 迁移时,必须保留旧 XOR 密钥 `MedicalReportSys2024` 才能解密历史 localStorage 中的 `systemSettings` 数据。首次修改后构建产物扫描发现该字符串仍然存在。
|
||||
|
||||
### B. 产生问题原因
|
||||
数据迁移需求(兼容旧 XOR 密文)与安全需求(消除硬编码密钥)表面上互斥。根源在于旧密钥是以明文常量形式写死在源码中的,构建产物必然包含该字符串。
|
||||
|
||||
### C. 解决问题方案
|
||||
将旧 XOR 密钥同样移入构建阶段环境变量 `LEGACY_STORAGE_KEY`,通过 `vite.config.ts` 的 `define` 注入:
|
||||
- 构建产物中不再包含固定的 `"MedicalReportSys2024"`。
|
||||
- 若部署方需要兼容旧数据,在构建时配置 `LEGACY_STORAGE_KEY="MedicalReportSys2024"` 即可正常迁移。
|
||||
- 若部署方不需要兼容(全新部署),留空即可,旧数据将以 JSON.parse 失败处理,回退到 fallback。
|
||||
|
||||
### D. 后续如何避免问题
|
||||
- 任何涉及历史数据迁移的安全重构,必须在方案设计阶段同步考虑"旧密钥/旧算法常量是否需要保留"。
|
||||
- 检查清单:若验收标准包含"构建产物无硬编码敏感字符串",则所有历史兼容所需的常量也必须环境变量化。
|
||||
- `.env.example` 中应显式标注 `LEGACY_STORAGE_KEY` 的用途("Former XOR encryption key"),避免运维人员误删。
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user