Commit Graph

4 Commits (06d0382dd81002041c2b4ca37d301843d021592e)

Author SHA1 Message Date
Council be9643b471 fix(phase4.1): 修正短码设计为【明文goods_id + 混淆ticket_id】
正确设计:
- 前4位:goods_id 明文 base36(直接可读)
- 后5位:ticket_id 经 Feistel8 混淆(保护 ticket_id)

编码流程:
1. goods_id → 4位 base36 明文
2. ticket_id → 5位 base36 → Feistel8 → 5位混淆密文
3. 拼接为9位短码

解码流程 O(1):
1. 前4位 base36_decode → goods_id
2. 用 goods_id 派生 key → Feistel8 解密后5位 → ticket_id
3. 无需暴力搜索,goods_id_hint 仅用于校验

优势:
- 解码 O(1),无需暴力搜索
- goods_id 明文暴露(可接受,ticket_id 仍被保护)
- ticket_id 受 Feistel8 混淆保护
2026-04-22 23:49:00 +08:00
Council 4df288c62a refactor(phase4.1): 短码设计改为明文 goods_id 方案,O(1) 解码
设计变更:
- 旧方案:位打包 (goods_id<<17|ticket_id),需要暴力搜索 goods_id
- 新方案:goods_id(4位base36) + ticket_id(5位base36) → Feistel8 → 短码

新设计优势:
- 解码 O(1):直接取前4位=goods_id,后5位=ticket_id
- 无需暴力搜索,只需验证 hint 匹配
- goods_id 范围扩大:0-1,679,615(4位base36)
- ticket_id 范围扩大:0-1,073,741,823(5位base36)
- 安全性不变:Feistel8 混淆仍保护 ticket_id

技术实现:
- shortCodeEncode: base36 固定4位/5位 padding → intval → Feistel8
- shortCodeDecode: 有 hint 直接验证,无 hint 暴力搜索
- 校验边界:goods_id ≤ 0xFFFFFF, ticket_id ≤ 0x3FFFFFFF
2026-04-22 23:37:33 +08:00
Council 223c4f3647 fix(phase4.1): 修复安全问题和代码优化
安全修复:
- getVrSecret(): 默认密钥必须 throw 异常阻断,不再仅 warning
  未配置 VR_TICKET_SECRET 时直接抛出异常,防止生产环境静默使用默认密钥

校验增强:
- shortCodeEncode(): 增加 goods_id 超 16bit 校验
  goods_id > 65535 时抛出异常,防止位截断静默错误

代码优化:
- shortCodeDecode(): 简化候选列表构建逻辑
  用 start/end 范围替代候选数组,消除冗余内存分配

测试补充:
- 添加 goods_id 超 16bit 边界测试
- 添加默认密钥异常说明测试
2026-04-22 23:26:31 +08:00
Council c3bf8ba2aa feat(phase4): Phase 4.1 基础设施 - Feistel-8 + QR签名 + 短码编解码
Phase 4.1 完成:
- BaseService.php 新增方法:
  - getVrSecret(): 获取 VR Ticket 主密钥
  - getGoodsKey(): per-goods key 派生(HMAC-SHA256)
  - feistelRound(): Feistel Round 函数(低19bit)
  - feistelEncode(): Feistel-8 混淆编码(8轮置换)
  - feistelDecode(): Feistel-8 解码(逆向8轮)
  - shortCodeEncode(): 短码生成(goods_id<<17 | ticket_id → Feistel8 → base36)
  - shortCodeDecode(): 短码解析(暴力搜索 goods_id)
  - signQrPayload(): QR payload 签名(HMAC-SHA256)
  - verifyQrPayload(): QR payload 验证(含过期检查)

位分配设计:
- goods_id: 高16bit(支持0-65535)
- ticket_id: 低17bit(支持0-131071)
- 总计33bit,Feistel-8混淆后转base36

安全特性:
- per-goods key 由 master_secret 派生,不同商品互相独立
- QR签名防篡改,HMAC-SHA256
- 30分钟有效期窗口

新增测试:
- tests/phase4_1_feistel_test.php
2026-04-22 18:51:22 +08:00