3.5 KiB
3.5 KiB
yh-platform 签名协议规范(v1.0)
权威源:Java
yh-utils-coreutils.crypto.SignUtil+yh-app-auth-spring-boot-starterSignCanonical。 本文档为双端(Java / C#)共同遵守的契约工件;任何变更须先改本文,再同步两侧实现。
1. 算法
统一使用 HmacSHA256,密钥与签名串均为 UTF-8 字节。
2. 双签名规则(长期并存,见方案 9.5 裁决 #5 收敛计划)
2.1 数据级签名(业务内容签名)
source = data + "|" + timestamp
output = HmacSHA256(source, secret) 的小写十六进制
timestamp = 毫秒级时间戳字符串
- 验签忽略大小写比对(
equalsIgnoreCase)。 verifyWithExpire:先比对签名,再校验|now - ts| <= expireMs(默认 5 分钟,双向偏差均拒绝)。
2.2 请求级签名(HTTP 请求签名,SDK 出站默认)
canonicalTarget = path + ("?" + sortedQuery # query 为空则不带
source = METHOD + "\n" + canonicalTarget + "\n" + timestamp
output = HmacSHA256(source, secret) 的 Base64
METHOD:大写(GET/POST),大小写敏感精确比对(这是既有行为,是否收敛见方案 9.5 裁决 #3)。path:只取路径,不含 host/port/context-path(保证服务发现/反代前后端天然对齐)。- basePath 剥离(客户端与服务端共同口径):客户端签名前从 path 剥离部署 basePath(与 UserBase 部署 context-path 一致,如
/userbase,对齐 JavaAppSignInterceptor.stripBasePath);服务端验签前剥request.getContextPath()(对齐 JavaAppAuthFilter)。剥离后 canonical 口径统一为/oapi/**。剥离规则:path 不以 basePath 开头时原样保留;剥离后为空或丢失前导斜杠时补/(/userbase→/)。 sortedQuery:query 按k=v整串字典序排序后以&连接;k、v 先 URL 解码再参与排序;多值参数的值也排序。- 验签为精确比对(Base64 区分大小写)。
verifyRequestWithExpire语义同数据级。- 测试向量中的
canonicalTarget即剥离后的服务端口径(含fullUrl/basePath字段可复现剥离前 URL)。
2.3 密钥约束
- secret 最小长度 16 位(
MIN_SECRET_LENGTH),低于此值签名方法抛参数异常。
3. HTTP 头契约(逐字一致)
| 头名 | 值 |
|---|---|
X-App-Key |
调用方在 UserBase 注册的 appKey |
X-Timestamp |
毫秒级时间戳字符串 |
X-Signature |
请求级签名(Base64) |
4. 防重放
- 时间窗口:
|now - X-Timestamp| > expireMs(默认 300000ms)即拒绝。 - nonce(可选扩展):同一
(appKey, timestamp, nonce)在窗口内只允许提交一次; Redis 键sign:replay:{appKey}:{timestamp}:{nonce},SETNX + TTL=窗口。
5. 验签密钥解析链(服务端)
1. Redis key = sign:app:{appKey} → 值为 SignAppKeyPayload JSON {appKey, secret, enabled}
2. 进程内缓存(Caffeine / IMemoryCache,TTL 5min)
3. 兜底 GET {userbase}/oapi/internal/sign-key/{appKey} → 信封 data 为 SignAppKeyPayload
- 仅当
enabled=true且secret非空才可用;未知 appKey 直接拒绝。 - 任一层异常静默降级到下一层(Redis 宕机不阻断业务)。
6. 测试向量
fixtures/sign-vectors.json:≥10 组向量(含空 body、超长参数、中文 UTF-8、query 排序、密钥长度边界、毫秒时间戳边界)。
基线由 Java SignUtil 实际运行产出;CI 中 Java 侧重算 fixture 防漂移,C# 侧逐字节对拍。