Secret 签名算法技术规范
一、算法目的
为防止接口恶意调用,所有请求需携带动态生成的secret参数。本规范详细说明secret的计算规则,服务端将通过相同算法验证请求合法性,拒绝无效签名。
二、算法流程图
[参数预处理] → [URL编码] → [ASCII排序] → [字符串拼接] → [Token追加] → [MD5哈希]
三、计算步骤说明
步骤1:参数预处理
1.过滤空值参数
移除参数名或参数值为空的字段(空字符串、null值等)
2.排除secret字段
需显式去除请求参数中的secret字段本身
预处理规则示例:
原始参数: {account: "40015752421", "corpId": "82734fee", secret: "B45A5E8F7DC1456BA4FC05FFEC351FA3", data="", reply=null "templateId": "220427091304079"}
处理后参数: {account: "40015752421", "corpId": "82734fee", "templateId": "220427091304079"}
步骤2:URL编码处理
对所有参数名和参数值进行application/x-www-form-urlencoded编码
编码字符集:UTF-8
注意保留已编码字符(如原参数值中的%20不做二次编码)
编码规则示例:
原始参数: data=["小明","小李"],mobile=13788888888,18699999999
编码结果: data=%5B%22%E5%B0%8F%E6%98%8E%22%2C%22%E5%B0%8F%E6%9D%8E%22%5D,mobile=13788888888%2C18699999999
步骤3:ASCII排序拼接
1.按参数名ASCII码升序排列
示例:account(97) < appver(97) < corpId(99) < data(100)
2.键值拼接规则
按排序后的顺序拼接为参数名1参数值1参数名2参数值2…格式
拼接示例:
排序后参数顺序: account, appver, corpId, data...
拼接结果: "account40015752421appver1corpId82734fee..."
步骤4:Token追加
在拼接字符串末尾直接追加系统分配的token
注意:token不做任何编码处理
追加示例:
拼接字符串 += "3551a828-ca81-40b5-af5d-54f39074a7d4"
步骤5:生成MD5签名
对最终字符串进行标准MD5哈希计算
输出要求:32位大写十六进制字符串
哈希示例:
输入字符串: "account40015752421...token"
MD5结果: "8DBA355E3830E234936F357834DA22E8"
四、完整示例演算
初始参数
{
"account": "40015752421",
"appver": "1",
"corpId": "82734fee-e05d-40df-b442-f29879c8b8a8",
"data": ["小明","小李"],
"mobile": "13788888888,18699999999",
"reply": 0,
"replyurl": null,
"secret": "B45A5E8F7DC1456BA4FC05FFEC351FA3",
"tag": "",
"templateId": "220427091304079",
"timestamp": "20250126111500",
"user": "40015752421_dev"
}
演算过程
1.预处理后参数
account=40015752421&appver=1&corpId=82734fee-e05d-40df-b442-f29879c8b8a8&data=["小明","小李"]&mobile=13788888888,18699999999&reply=0&templateId=220427091304079×tamp=20250126111500&user=40015752421_dev
2.URL编码结果
account=40015752421
appver=1
corpId=82734fee-e05d-40df-b442-f29879c8b8a8
data=%5B%22%E5%B0%8F%E6%98%8E%22%2C%22%E5%B0%8F%E6%9D%8E%22%5D
mobile=13788888888%2C18699999999
reply=0
templateId=220427091304079
timestamp=20250126111500
user=40015752421_dev
3.排序拼接结果
"account40015752421appver1corpId82734fee-e05d-40df-b442-f29879c8b8a8data%5B%22%E5%B0%8F%E6%98%8E%22%2C%22%E5%B0%8F%E6%9D%8E%22%5Dmobile13788888888%2C18699999999reply0templateId220427091304079timestamp20250126111500user40015752421_dev"
4.最终哈希输入
"account40015752421appver1corpId82734fee-e05d-40df-b442-f29879c8b8a8data%5B%22%E5%B0%8F%E6%98%8E%22%2C%22%E5%B0%8F%E6%9D%8E%22%5Dmobile13788888888%2C18699999999reply0templateId220427091304079timestamp20250126111500user40015752421_dev3551a828-ca81-40b5-af5d-54f39074a7d4"
5.生成Secret
可通过一下方式验证:
import hashlib
s = "account40015752421appver1corpId82734fee-e05d-40df-b442-f29879c8b8a8data%5B%22%E5%B0%8F%E6%98%8E%22%2C%22%E5%B0%8F%E6%9D%8E%22%5Dmobile13788888888%2C18699999999reply0templateId220427091304079timestamp20250126111500user40015752421_dev3551a828-ca81-40b5-af5d-54f39074a7d4"
print(hashlib.md5(s.encode()).hexdigest().upper())
最终计算结果:
8DBA355E3830E234936F357834DA22E8
五、注意事项
1.编码一致性
确保URL编码实现符合RFC 3986标准,Python推荐使用urllib.parse.quote,Java推荐使用URLEncoder.encode
重点关注一下编码差异:
原始字符 URL编码后
[ %5B
" %22
, %2C
中文 %E5%B0%8F%...
边界案例测试
空数组参数:data=[] → data%5B%5D
纯数字参数:mobile=1380013800 → 无需编码
布尔值参数:reply=true → replytrue
2.排序稳定性
当参数名相同时(理论上不应存在),需保持参数原始顺序
3.空值处理
参数值为0、false等有效值需保留,仅过滤真正空值参数
4.测试验证
建议使用官方提供的在线验证工具进行算法正确性校验
5.安全建议
token需严格保密,建议定期轮换,禁止在客户端硬编码
文档更新时间: 2025-02-20 16:55 作者:admin