# 接口签名算法说明 ## 概述 本接口使用 **HMAC-MD5** 算法对请求参数进行签名,以确保请求的合法性与完整性,防止请求被篡改或伪造。 生成的sign值放在header中,key=X-sign,value=加密值。 --- ## 签名生成流程 ``` 请求参数 │ ▼ ① 参数递归排序(ksort) │ ▼ ② 构造签名字符串(key=value&key=value...) │ 数组/对象类型 → JSON 字符串 ▼ ③ HMAC-MD5(query_string, secret_key) │ ▼ sign(签名结果) ``` --- ## 详细步骤 ### 第一步:参数递归排序 对所有请求参数按照**键名字典序(ksort)进行递归排序**,嵌套数组也需同样处理,以保证双方构造字符串的顺序一致。 ### 第二步:构造签名字符串 遍历排序后的参数,按以下规则拼接为字符串: | 参数类型 | 处理方式 | | ------------------------ | -------------------------------------------------------- | | 普通值(字符串、数字等) | 直接使用原始值 | | 数组 / 对象 | 转为 JSON 字符串(中文不转义,`JSON_UNESCAPED_UNICODE`) | 拼接格式: ``` key1=value1&key2=value2&key3=value3 ``` > ⚠️ **注意**:参数值**不做 URL encode**,与 `http_build_query` 的行为不同。数组参数也**不展开**为 `key[0]=...` 形式,而是整体转为 JSON 字符串。 ### 第三步:计算签名 使用 `secret_key` 对上一步得到的字符串执行 **HMAC-MD5** 计算: ``` sign = HMAC-MD5(query_string, secret_key) ``` --- ## 示例 ### 原始请求参数 ```json { "uid": 1001, "amount": 100, "currency": "CNY", "items": [ { "id": 1, "name": "商品A" } ] } ``` ### 第一步:排序后的参数顺序 ``` amount, currency, items, uid ``` ### 第二步:构造签名字符串 ``` amount=100¤cy=CNY&items=[{"id":1,"name":"商品A"}]&uid=1001 ``` ### 第三步:计算签名 ``` sign = HMAC-MD5("amount=100¤cy=CNY&items=[{\"id\":1,\"name\":\"商品A\"}]&uid=1001", "your_secret_key") ``` --- ## 注意事项 | 项目 | 说明 | | -------- | -------------------------------------------------------- | | 排序方式 | 字典序递归排序,嵌套数组也要排序 | | 数组参数 | 转为 JSON 字符串,中文不转义(`JSON_UNESCAPED_UNICODE`) | | URL 编码 | 参数值**不做** URL encode | | 数组展开 | **不展开**为 `key[0]=...` 形式 | | 密钥管理 | `secret_key` 需双方提前约定,**严禁在请求中传输** | | 算法 | HMAC-MD5,输出为 32 位十六进制小写字符串 | --- 密钥: H6p*2RfEu4ITcL