三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

看球直播接口逆向分析:签名机制与 AES 解密实战

看球直播接口逆向分析:签名机制与 AES 解密实战

在爬取或分析直播流媒体数据时,绝大多数平台都会通过加签、加密等手段来防止第三方直接获取数据。最近对““看球直播””的接口进行了逆向分析,整个过程比较典型,包含了签名加盐AES-CBC 响应加密,今天我把分析过程记录下来,希望对大家有所帮助。

一、目标接口定位与抓包分析

首先,打开浏览器开发者工具(F12),切换到 Network 面板,触发直播请求。很快就能定位到核心数据接口。
在请求参数中,我们发现了几个关键字段:

  • room_id: 直播间 ID
  • code_id,match_id,sport_id: 赛事相关标识
  • time: 时间戳
  • signature:请求签名(显然是动态加密生成的)

二、 Signature 签名生成算法逆向

1. 定位签名生成函数

在 Sources 面板中,搜索signature关键字,或者通过 XHR 断点逐步跟踪,可以定位到核心代码。

LiveDetails模块中,有一个generateSignature方法。断点打下后,进入函数内部。

2. 拆解签名算法逻辑

通过观察 JS 调用栈与作用域,可以明确签名的生成步骤如下:

  1. 参数排序拼接
    先将请求参数对象n(包含code_id,ios_status,match_id,room_id,sport_id,time)的所有 key 进行字母排序(Object.keys(n).sort())。
  2. 键值对拼接
    按照排序好的 key,将 key 和对应的 value 连成字符串。例如:code_idbqzmios_status1match_id4546337room_id88888888sport_id1time1785982581
  3. 加盐处理
    经过动态调试和测试,发现这段拼接后的字符串需要附加一个固定的盐值(Salt),盐值为yKBm0pKLdVcGbnu4XGon13TsyBdEsjj3WVAzszpoqjn3BNmovLgzvcRTxD1Wey7QQ10kcov0b8e9oBi7jAUR
  4. MD5 运算
    拼接完整后,进行 MD5 哈希计算,生成 32 位小写字符串,即为最终的signature字段。

💡 补充说明
这里我是通过经验看出来它是做的 MD5 加密。如果是新手同学,可以根据图片所示点击跳转到函数内部仔细研究下对应的加密代码。码## 三、返回数据 AES 解密流程分析析

拿到加密的响应数据后,下一个任务就是找到解密函数。
getRoomPlayUrl请求成功后,数据进入了this.decryptPlayData(e)方法。

进入该解密函数,我们能清晰地看到加密模式:*加密库:使用的是crypto-js标准库。

  • 加密算法AES-CBC模式。
  • 填充模式Pkcs7

核心密钥与 IV 生成分析
代码中定义了一个变量s0,然后通过以下代码生成了密钥(Key)和偏移量(IV):

constb=e.aes.enc.Latin1.parse(s0.substring(0,16));// IVconstt=e.aes.enc.Latin1.parse(s0);// Key

也就是说,密钥就是s0本身,而 IV 是s0的前 16 个字符
那么s0是从哪来的呢?结合图 4 的观察,这里有一段非常反爬的混淆代码,通过数组u(包含大量的 ASCII 码)和a动态生成了一个字符串。我们需要通过动态断点,把运行时真正计算出来的s0值复制出来(扣出 JS 中的s0即可),用于后续 Python 代码的解密。

四、 Python 还原请求与解密完整逻辑

基于以上分析,我们可以使用 Python 编写一套完整的模拟请求脚本。

1. 签名生成复现

importhashlibimporttimeimportrequestsdefgenerate_signature(params):# 1. 参数排序并拼接sorted_keys=sorted(params.keys())base_str="".join([f"{k}{params[k]}"forkinsorted_keys])# 2. 拼接盐值salt="yKBm0pKLdVcGbnu4XGon13TsyBdEsjj3WVAzszpoqjn3BNmovLgzvcRTxD1Wey7QQ10kcov0b8e9oBi7jAUR"sign_str=base_str+salt# 3. 计算 MD5signature=hashlib.md5(sign_str.encode('utf-8')).hexdigest()returnsignature# 构建参数params={"room_id":"88888888","code_id":"bqzm","time":int(time.time()),# 必须使用动态当前时间戳"match_id":"4546337","sport_id":"1","ios_status":1}# 生成签名params["signature"]=generate_signature(params)print(f"生成的签名:{params['signature']}")

2. 响应数据 AES 解密复现

假设我们已经从混淆 JS 中扣出了密钥s0,假设为"your_extracted_key_here"

importbase64fromCrypto.CipherimportAESdefdecrypt_response(encrypted_text,key_string):# 提取 Key 和 IV# 注意:crypto-js 的 Latin1.parse 对应 Python 的 latin-1 编码key=key_string.encode('latin-1')iv=key[:16]# 取密钥的前16位作为IV# Base64 解码密文ciphertext=base64.b64decode(encrypted_text)# AES-CBC Pkcs7 解密cipher=AES.new(key,AES.MODE_CBC,iv)plain_text=cipher.decrypt(ciphertext)# 去除 Pkcs7 填充padding_len=plain_text[-1]returnplain_text[:-padding_len].decode('utf-8')

代码运行结果截图

结语

通过上述几步,我们成功逆向了“看球直播”的接口。在整个过程中,加密库的选择(crypto-js)加盐 MD5以及AES CBC 模式解密都是非常经典的 Web 反爬手段。实际应用中,除了算法还原,还需要注意网站可能会动态更新盐值或更新混淆的 JS 代码,破解后建议定期检查算法的有效性。希望这篇文章能够为想要进行类似 Web 逆向的朋友提供参考思路!

免责声明:本文仅供技术学习与交流,请勿用于商业用途或恶意爬取。大家在实战中也应遵循网站的robots.txt协议,文明爬虫。

← 返回列表