Files
Mdeical_Sur_Report/工程分析/实现方案-2026-04-20-10-14-09.md

7.1 KiB
Raw Blame History

实现方案

时间戳2026-04-20-10-14-09 对应需求分析:需求分析-2026-04-20-10-14-09.md


1. 方案概述

在不改变 storage.get/set 同步调用签名的前提下,将 systemSettings 的底层加密从 XOR 迁移至 Web Crypto API AES-GCM密钥与 API Key、授权哈希全部移入构建阶段环境变量。应用启动时异步初始化存储模块预解密 systemSettings 到内存缓存,后续同步读写均走缓存。旧 XOR 密文自动识别并迁移。UserManage.tsx 中的明文授权常量替换为 SHA-256 环境变量哈希比对,同时以最小代价替换原生 alert/confirm 为内联状态提示。


2. 详细改动清单

2.1 文件src/utils/storage.ts

行号范围 改动类型 说明
1-6 删除 移除 API_KEY_CODES 数组与 getDefaultApiKey() 的旧实现
8 修改 CRYPTO_KEY 改为从 process.env.STORAGE_KEY 读取,并更名为 LEGACY_CRYPTO_KEY
10-25 保留 xorEncrypt / xorDecrypt 保留用于向后兼容读取
新增 新增 引入 Web Crypto APIimportCryptoKeyaesEncryptaesDecrypt
新增 新增 AES_GCM_PREFIX = 'ag:' 用于识别新格式密文
新增 新增 systemSettingsCacheinitPromise 等模块级状态
新增 新增 异步 init() 函数:导入密钥、预加载 systemSettings、自动迁移旧数据
27-43 修改 get()systemSettings 改为从内存缓存返回
45-55 修改 set()systemSettings 改为更新缓存并触发异步 persistSystemSettings()
新增 新增 sha256(text) 工具函数Web Crypto API供 UserManage.tsx 使用

关键代码逻辑

// AES-GCM 密文格式: ag:<base64(iv)>:<base64(ciphertext)>
const AES_GCM_PREFIX = 'ag:';

async function init() {
  const keyData = process.env.STORAGE_KEY || '';
  if (!keyData) throw new Error('STORAGE_KEY not configured in build env');
  cryptoKey = await crypto.subtle.importKey(
    'raw',
    new TextEncoder().encode(keyData.padEnd(32, '0').slice(0, 32)),
    { name: 'AES-GCM' },
    false,
    ['encrypt', 'decrypt']
  );
  const raw = localStorage.getItem('systemSettings');
  if (raw) {
    if (raw.startsWith(AES_GCM_PREFIX)) {
      systemSettingsCache = await aesDecrypt(raw);
    } else {
      try { systemSettingsCache = JSON.parse(raw); }
      catch { systemSettingsCache = JSON.parse(xorDecrypt(raw, LEGACY_KEY)); }
      await persistSystemSettings(); // 静默迁移
    }
  }
}

2.2 文件src/main.tsx

行号范围 改动类型 说明
4-10 修改 包装为异步 bootstrap(),先 await storage.init() 再 render App
import { storage } from './utils/storage';
async function bootstrap() {
  await storage.init();
  createRoot(document.getElementById('root')!).render(
    <StrictMode><App /></StrictMode>
  );
}
bootstrap();

2.3 文件vite.config.ts

行号范围 改动类型 说明
10-12 修改 define 中新增 4 个环境变量注入
define: {
  'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
  'process.env.STORAGE_KEY': JSON.stringify(env.STORAGE_KEY),
  'process.env.DEFAULT_API_KEY': JSON.stringify(env.DEFAULT_API_KEY),
  'process.env.ADMIN_AUTH_HASH': JSON.stringify(env.ADMIN_AUTH_HASH),
  'process.env.ADMIN_AUTH_SALT': JSON.stringify(env.ADMIN_AUTH_SALT),
},

2.4 文件:.env.example

行号范围 改动类型 说明
新增 新增 追加 4 个必需环境变量模板
# 本地存储 AES-GCM 加密密钥(建议 32 位随机字符串)
STORAGE_KEY="YourRandom32CharKeyHere!!!"

# 默认 AI API Key替代原 API_KEY_CODES 硬编码)
DEFAULT_API_KEY="your-api-key-here"

# 禁用管理员操作的授权码 SHA-256 哈希值hex 小写)
ADMIN_AUTH_HASH="your-sha256-hash-here"

# 授权码哈希盐值
ADMIN_AUTH_SALT="your-random-salt-here"

2.5 文件src/pages/UserManage.tsx

行号范围 改动类型 说明
8 删除 移除 ADMIN_DISABLE_AUTH_KEY = 'DISABLE_ADMIN_2024'
新增 新增 从环境变量读取 ADMIN_AUTH_HASHADMIN_AUTH_SALT
29 修改 authKey 保持,但比对逻辑改为 SHA-256
新增 新增 增加 errorMessageconfirmDialog 状态替换 alert/confirm
103-116 修改 handleDelete 改为触发确认对话框状态,移除 window.confirm
118-154 修改 handleEdit 中 alert 改为设置 errorMessage
185-324 修改 handleSubmit 改为 async所有 alert 改为 errorMessage,授权比对改为 await sha256(authKey + salt)
新增 JSX 新增 表单顶部增加错误提示条;新增轻量确认对话框覆盖层

3. 关键设计决策

决策点 选择方案 备选方案 不选备选的原因
systemSettings 异步加密的同步接口兼容 模块初始化时预解密到内存缓存get/set 保持同步 将 storage.get/set 全局改为 async 调用点超过 50 处,改动面过大,风险不可控
AES-GCM 密钥长度处理 将环境变量字符串 padEnd 到 32 字节后截断 要求用户必须提供 32 字节 提升用户体验,减少配置门槛
旧数据迁移时机 init() 中自动检测并静默迁移 提供手动迁移脚本 纯前端无脚本执行环境,自动迁移对用户透明
SHA-256 实现选择 Web Crypto API已在 storage.ts 提供工具函数) crypto-js 同步计算 统一使用 Web Crypto API减少额外依赖引用
alert/confirm 替换策略 内联状态提示条 + 轻量确认状态 抽取全局 Modal 组件 项目中无现成 Modal本次以最小代价消除明文暴露和原生弹窗

4. 与现有规范的兼容性检查

  • contentEditable 编辑器规范5.1 — 本次不涉及编辑器
  • 自动保存与草稿机制5.2 — storage 接口签名不变ReportEditor 自动保存逻辑无影响
  • 图片与视频处理5.3 — 本次不涉及
  • 智能字段与动态表单5.4 — 本次不涉及
  • AI 功能开发规范5.5getDefaultApiKey() 返回值不变,调用方无感知
  • 数据迁移与类型安全5.6 — 旧 XOR 密文自动迁移,使用 (obj as any).oldField 安全访问思路已体现在旧格式兼容分支
  • UI/UX 通用规范5.7 — UserManage.tsx 中原生 alert/confirm 全部替换为自定义状态提示

5. 回滚策略

若构建失败或运行异常:

git reset --hard HEAD~1

或手动还原:

  1. 恢复 src/utils/storage.ts 中的 XOR 逻辑与 API_KEY_CODES
  2. 恢复 src/pages/UserManage.tsx 中的 ADMIN_DISABLE_AUTH_KEY
  3. 恢复 src/main.tsx 为同步 render
  4. 还原 vite.config.ts 的 define 配置

6. 预估工作量

阶段 预估时间
代码修改 25 min
测试验证 15 min
文档更新 10 min

状态 用户已豁免人工审核确认