外观
V1 / V3 签名
协议版本由项目配置决定。V1 与 V3 的路由和签名完全不同,客户端不能通过请求参数临时切换。
V3 HMAC-SHA256(推荐)
V3 卡密登录地址:
http
POST /api/legacy/v3/cards/login
Content-Type: application/x-www-form-urlencoded
X-GN-Timestamp: 1720000000
X-GN-Nonce: RANDOM_UNIQUE_NONCE
X-GN-Signature: UPPERCASE_HEX_HMAC规范串:
text
METHOD\nACTION\nPROGRAM_ID\nTIMESTAMP\nNONCE\nSHA256(QUERY)\nSHA256(BODY)签名:
text
UPPER_HEX(HMAC_SHA256(canonical, sign_key))卡密登录的 ACTION 固定为 card_login。参与哈希的 BODY 必须与实际发送的原始请求体字节完全一致。
V3 请求头
| 请求头 | 要求 | 说明 |
|---|---|---|
X-GN-Timestamp | 必填 | 当前秒级 Unix 时间戳 |
X-GN-Nonce | 必填 | 16-96 位,每次请求唯一 |
X-GN-Signature | 必填 | 大写十六进制 HMAC-SHA256 |
V1 MD5(旧项目)
V1 仅保留存量兼容,新接入一律使用 V3。以下是当前服务端 LegacyCryptoService::generateLegacyV1Sign() 的实际行为。
- 取请求中实际传入的全部参数(含业务字段与
t),顺序即参数到达服务端的顺序。 - 排除以下固定字段:
s、sign、safe_code、app、value、PHPSESSID、sec_defend、sidenav-state,以及api。 - 排除所有以
_开头的内部字段。 - 数组和对象类型的值直接跳过,不参与签名;布尔值按
1/0字符串化。 - 按
key=value&依次拼接,末尾保留一个&。 - 计算
MD5(拼接结果 + 签名密钥)。服务端生成 32 位小写十六进制;校验时会把收到的sign统一转小写再比对(LegacyCryptoService.php:193),因此客户端提交大写或小写均可。
V1 与常见文档描述的三处差异
- 不跳过空字符串:值为空串的字段仍会以
key=&参与拼接。客户端不要自行剔除空值字段。 - 不排序:服务端按请求参数的实际顺序拼接。客户端必须保证发送顺序与签名顺序完全一致,不要按 ASCII 重排。
- 末尾带
&:拼接串以&结尾,不是在最后一项后省略。
以上三点任一不符都会导致签名校验失败。若客户端难以稳定复现请求顺序,请改用 V3。
WARNING
V3 不会回退兼容 V1。切换项目协议后,必须同时更新客户端地址和签名实现。