在网络爬虫、接口抓包、自动化接口调用场景中,几乎所有正规平台的请求都会携带签名参数(sign) ,用于校验请求合法性、防止篡改、重放与恶意调用。想要实现稳定的接口调用,核心就是逆向分析 sign 生成算法。本文从原理、常见加密形式、抓包定位、代码还原到反制思路,完整讲解 sign 参数逆向全流程。
一、sign 签名的核心作用
sign 本质是服务端与客户端约定的哈希 / 加密摘要,通过对请求参数、时间戳、随机串、密钥等进行组合计算得出,服务端收到请求后会用相同规则重新计算并比对,不一致则直接拒绝。
核心作用:
- 防止请求参数被篡改
- 防止接口被无脑刷量、爬虫滥用
- 绑定设备、用户、时间,限制重放攻击
- 区分合法客户端与非法调用
二、sign 最常见的生成结构(通用模板)
绝大多数网站 / APP 的 sign 都遵循固定套路,典型组合如下:
plaintext
sign = MD5( 有序参数拼接 + 盐值/密钥 + timestamp + nonce )
常见组成部分:
- 请求参数(按 key 字典序排序,拼接为 key1=value1&key2=value2)
- 固定盐值(secret):写死在前端代码或配置中
- 时间戳 timestamp(秒 / 毫秒),防重放
- 随机串 nonce:一次一随机
- 设备标识(uuid、deviceId、oaid)
- 用户 token /uid
常见哈希算法优先级:MD5 > SHA1 > SHA256 > HMAC,少量会使用 AES、RSA 或自定义异或、移位、拼接变种。
三、逆向 sign 的标准流程(实战步骤)
1. 抓包定位 sign 参数
使用工具:
- Web:Chrome DevTools(Network)、Fiddler、Charles
- APP:Charles、Burp Suite、Frida + 模拟器
重点观察:
- 请求头或参数中是否有
sign、signature、_sign、token等关键字段 - 同一接口多次请求,哪些字段变化(timestamp、nonce、sign),哪些不变
- 判断 sign 长度:32 位大概率 MD5,40 位 SHA1,64 位 SHA256
2. 定位前端加密代码(关键!)
Web 端核心思路:全局搜索关键词在 js 中搜索:
plaintext
sign=
signature
md5(
sha1(
sha256(
encrypt(
常见位置:
- 公共 request 封装函数(axios/fetch 拦截器)
- 工具类 utils.js、crypto.js
- 混淆 / 压缩后的 vendor.js、chunk.js
APP 端思路:
- 反编译 APK 找 Java/Kotlin 加密逻辑
- 使用 Frida hook 加密函数(MessageDigest、HMAC、自定义类)
3. 对比明文与密文,推导拼接规则
逆向核心是控制变量法:
- 只改一个参数,看 sign 是否变化
- 去掉 timestamp,看 sign 是否变化
- 调整参数顺序,看 sign 是否变化
- 替换为固定值,暴力比对哈希结果
典型案例(伪代码):
plaintext
// 前端逻辑
params = {a:1, b:2, timestamp:1735000000}
sorted_str = "a=1&b=2×tamp=1735000000"
sign = md5(sorted_str + "abc123_secret")
4. 还原算法(Python 示例)
以最常见 MD5 有序参数 + 盐值 为例:
python
运行
import hashlib
def generate_sign(params, secret="abc123_secret"):
# 1. 按 key 字典序排序
sorted_items = sorted(params.items(), key=lambda x: x[0])
# 2. 拼接成 k=v&k=v
param_str = "&".join([f"{k}={v}" for k, v in sorted_items])
# 3. 拼接盐值
raw_str = param_str + secret
# 4. MD5 并转小写
sign = hashlib.md5(raw_str.encode("utf-8")).hexdigest().lower()
return sign
# 测试
params = {
"a": 1,
"b": 2,
"timestamp": 1735000000
}
print(generate_sign(params))
四、常见进阶 sign 加密形态(必须识别)
1. HMAC 系列(带密钥的哈希)
plaintext
sign = HMAC-SHA256( secret, data ).hexdigest()
特点:需要密钥,安全性高于普通 MD5。
2. 自定义拼接变种
- 前后加字符串:
md5("prefix" + data + "suffix") - 参数值拼接不拼接 key:
md5("12"+"abc"+"1735000000") - 全部大写 / 小写、截取前 32 位
3. 时间戳参与多次哈希
plaintext
ts = str(int(time.time()))
sign = md5( md5(params+ts) + ts + secret )
4. JS 混淆 / VM 加密(常见于大厂)
特征:
- 代码被 uglify、obfuscator 混淆
- 加密逻辑在 WebAssembly、eval、new Function 中
- 采用大数组字符串解密、控制流平坦化
应对:
- 用 AST 反混淆、断点调试
- hook
CryptoJS.MD5、md5等函数 - 使用 PyExecJS、Node.js 直接调用原 JS 函数
五、sign 逆向常见坑与避坑指南
- 参数顺序错误 :绝大多数必须字典序,乱序必错
- 编码问题 :中文 / 特殊字符需
UTF-8、URLencode - timestamp 精度:秒级 / 毫秒级必须一致
- 隐藏字段 :headers 中的
deviceId、clientType也可能参与签名 - 大小写:MD5 大写 / 小写必须严格匹配
- 空值处理 :
key=与无该 key 结果不同
六、合法边界与合规提醒
sign 逆向仅可用于:
- 个人学习、接口协议研究
- 自身产品调试、自动化测试
- 授权渗透测试(持授权书)
严禁用于:
- 未经许可爬取商业数据、刷接口、薅羊毛
- 破坏平台服务、批量注册、恶意调用
- 绕过权限、越权获取数据
技术中立,行为合规才是底线。
七、总结
sign 签名逆向本质是 **"找参数、排顺序、拼字符串、猜哈希、验结果"** 的工程化过程,90% 的场景都是 MD5/SHA1 + 有序参数 + 盐值 + 时间戳。
掌握这套思路后,无论 Web、小程序、APP 接口,都能快速定位加密逻辑、还原算法,实现稳定、低风险的接口调用。