TypechoJoeTheme

至尊技术网

统计
登录
用户名
密码

某保险资讯App请求头token与sign加密算法逆向分析

2025-08-12
/
0 评论
/
2 阅读
/
正在检测是否收录...
08/12

本文通过完整的逆向工程流程,深度解析某保险资讯App的请求头加密机制,包括token动态生成策略与sign签名算法实现原理,提供详细的算法还原方法与代码实现。


一、初探请求头加密特征

在使用Charles抓包分析该App的HTTPS流量时,发现所有业务请求头都包含两个关键参数:
http token: 0xFA8B2C...(32位十六进制字符串) sign: 9a7f45...(40位SHA1哈希)

通过连续抓包对比发现三个特征:
1. token在用户登录后固定不变
2. sign随每次请求发生变化
3. 未携带参数时sign仍会生成

二、动态调试定位加密点

2.1 环境准备

  • 真机:Redmi Note 11 Pro(Android 12)
  • 工具:Frida + Jadx + IDA Pro

2.2 关键定位过程

通过拦截okhttp3请求框架,发现最终调用链:
java com.insurance.secure.util.SecurityHelper ├─ generateToken() // 设备指纹生成 └─ generateSign(String param) // 动态签名生成

使用Frida主动调用验证:
javascript Interceptor.attach(Module.findExportByName("libnative.so", "Java_com_insurance_secure_util_SecurityHelper_generateSign"), { onEnter: function(args) { console.log("Sign Params:", Java.vm.getEnv().getStringUtfChars(args[2], null).readCString()); } });

三、token生成算法还原

逆向分析发现token由三部分组成:
0x[设备指纹][时间戳][CRC校验码]
具体实现代码:
python def generate_token(): android_id = get_system_property("ro.serialno") # 取设备序列号 timestamp = int(time.time() * 1000) raw_token = f"{android_id}|{timestamp}" crc32 = binascii.crc32(raw_token.encode()) & 0xFFFFFFFF return f"0x{android_id[:8]}{timestamp:x}{crc32:08x}"

关键点:
- 使用设备硬件信息保证唯一性
- 未登录时生成临时token
- 登录后服务端返回持久化token

四、sign签名算法深度解析

通过Hook发现sign生成包含5个步骤:

  1. 参数标准化java
    // 示例请求参数
    {
    "page": 1,
    "size": 20,
    "timestamp": 1659345678123
    }

// 处理规则:
// 1. 按key字母排序
// 2. 过滤value为null的字段
// 3. 用=连接key-value,&连接不同字段
→ "page=1&size=20×tamp=1659345678123"

  1. 拼接固定盐值
    python salt = "@#Insurance$2023!" raw_sign = sorted_params + salt

  2. 双重哈希处理
    c // 伪代码实现 MD5(md5(raw_sign).substr(8,16) + token)

  3. 大小写转换
    将结果字符串中第3、7、11位字符转为大写

  4. 最终编码
    python final_sign = base64_encode(sha1(processed_str)).substr(0,40)

五、算法安全性与对抗建议

该加密方案存在三处可优化点:
1. 盐值硬编码风险:so文件中静态字符串可通过字符串搜索定位
2. 设备指纹伪造:通过Xposed模块可伪造android_id等参数
3. 签名时效缺失:未绑定请求时间有效性校验

企业级加固建议:
- 采用动态盐值下发机制
- 增加请求时间窗口验证
- 关键算法使用白盒加密实现

六、完整实现代码

Python版签名生成器:python
import hashlib
import base64

def generatesign(params: dict, token: str): # 参数排序处理 sortedparams = '&'.join([f"{k}={v}" for k,v in sorted(params.items()) if v])

# 拼接盐值
SALT = "@#Insurance$2023!"
raw_str = sorted_params + SALT

# 双重哈希
stage1 = hashlib.md5(raw_str.encode()).hexdigest()[8:24]
stage2 = hashlib.md5((stage1 + token).encode()).hexdigest()

# 大小写转换
sign_list = list(stage2)
for pos in [2,6,10]:
    sign_list[pos] = sign_list[pos].upper()

# 最终编码
return base64.b64encode(
    hashlib.sha1(''.join(sign_list).encode()).digest()
).decode()[:40]

朗读
赞(0)
版权属于:

至尊技术网

本文链接:

https://www.zzwws.cn/archives/35579/(转载时请注明本文出处及文章链接)

评论 (0)