news 2026/6/20 5:48:47

JS逆向实战:解密某查查网动态请求头的HmacSHA512加密

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JS逆向实战:解密某查查网动态请求头的HmacSHA512加密

1. 从点击关注到发现加密参数

最近在研究某查查网的关注功能时,发现它的API请求头里有两个神秘的参数:key和val。每次请求时这两个值都会变化,明显是某种动态加密的结果。作为一个喜欢刨根问底的技术人,我决定深入探究一下这个加密机制。

打开Chrome开发者工具,切换到Network面板,勾选Preserve log选项。登录某查查网后,随便搜索一家公司点击关注,在XHR请求中果然看到了这个带着加密参数的请求。仔细观察发现,这两个参数并不是简单的随机字符串,而是有规律的加密结果。

为了找到加密逻辑的源头,我在XHR请求上设置了断点。点击关注按钮触发断点后,通过Call Stack面板逐层向上追踪调用栈。这个过程就像侦探破案一样,需要耐心地一层层排查。最终在某个异步回调函数中发现了关键线索 - 这里调用了f.request方法,而加密参数的生成就在这个调用链中。

2. 逆向分析加密逻辑

2.1 定位关键加密函数

通过断点调试,我发现加密过程主要分为两个部分:key的生成和val的生成。这两个值都使用了HmacSHA512加密算法,但输入的参数有所不同。

key的生成流程是这样的:

  1. 将API接口路径转换为小写
  2. 将路径字符串重复拼接两次
  3. 对每个字符的Unicode码进行特定运算
  4. 通过一个固定的映射表生成中间密钥
  5. 用这个密钥对API路径和请求体数据进行HmacSHA512加密
  6. 最后取加密结果的第8到28位作为最终的key
// 类似这样的代码逻辑 function generateKey(apiPath, requestData) { const codeMap = { /* 省略映射表 */ }; let tempKey = ''; const doublePath = apiPath.toLowerCase() + apiPath.toLowerCase(); for(let char of doublePath) { const code = char.charCodeAt(0); const index = code % Object.keys(codeMap).length; tempKey += codeMap[index]; } // 后续进行HmacSHA512加密... }

2.2 解密val的生成过程

val的生成比key更复杂一些,除了API路径和请求数据外,还引入了一个额外的tid参数。这个tid是从网页的全局变量window.tid中获取的,每次页面加载都会变化。

具体步骤:

  1. 拼接API路径、"pathString"、请求体数据和tid
  2. 使用与key相同的密钥生成方法
  3. 对拼接后的字符串进行HmacSHA512加密
  4. 取完整加密结果作为val
# Python示例代码片段 def generate_val(api_path, data, tid): data_str = json.dumps(data, separators=(',', ':')).lower() combined = api_path + "pathString" + data_str + tid # 后续加密逻辑...

3. 完整Python实现

3.1 构建加密工具函数

经过上面的分析,我们可以用Python完整复现这个加密过程。首先需要准备两个核心函数:

import hashlib import hmac import json def hmac_sha512(key, data): """HmacSHA512加密函数""" hmac_obj = hmac.new(key.encode(), data.encode(), digestmod=hashlib.sha512) return hmac_obj.hexdigest() def generate_codes(api_path): """生成加密用的中间密钥""" code_map = { "0": "W", "1": "l", "2": "k", "3": "B", "4": "Q", "5": "g", "6": "f", "7": "i", "8": "i", "9": "r", "10": "v", "11": "6", "12": "A", "13": "K", "14": "N", "15": "k", "16": "4", "17": "L", "18": "1", "19": "8" } lower_path = api_path.lower() double_path = lower_path + lower_path codes = '' for char in double_path: code = ord(char) % len(code_map) codes += code_map[str(code)] return codes

3.2 组装完整请求头

有了基础函数后,就可以实现完整的请求头生成了:

def generate_headers(api_path, request_data, tid): """生成加密请求头""" # 准备数据 data_str = json.dumps(request_data, separators=(',', ':')).lower() # 生成key key_data = api_path + data_str temp_key = generate_codes(api_path) header_key = hmac_sha512(temp_key, key_data).lower()[8:28] # 生成val val_data = api_path + "pathString" + data_str + tid temp_val_key = generate_codes(api_path) header_val = hmac_sha512(temp_val_key, val_data) return {header_key: header_val} # 使用示例 if __name__ == '__main__': api = "/api/user/addfollowinglist" data = {'companyKeyno': "6e9104e7983f72a2178aa189a1ab8d54"} tid = "2727b92fa87a73d7fe2d4bef8324ea61" # 需要从网页中获取 headers = generate_headers(api, data, tid) print(headers)

4. 实战中的注意事项

4.1 如何获取tid参数

tid参数是这个加密体系中的重要一环,它存储在网页的全局变量window.tid中。在实际应用中,我们需要先访问网页获取这个值。可以通过以下方式:

  1. 使用requests库先请求首页
  2. 用正则表达式或HTML解析器提取tid
  3. 将tid用于后续的API请求
import re import requests def get_tid(): response = requests.get('https://www.qcc.com/') tid_match = re.search(r'window\.tid\s*=\s*["\']([^"\']+)["\']', response.text) if tid_match: return tid_match.group(1) raise Exception("Failed to extract tid")

4.2 处理动态变化的参数

在实际使用中发现,除了tid会变化外,某些API的请求参数也可能包含时间戳或随机数。这就需要我们:

  1. 仔细分析每个API的请求参数
  2. 识别哪些是固定值,哪些是动态生成的
  3. 对动态参数找到其生成规律或获取方式

4.3 调试技巧分享

在逆向过程中,我总结了一些实用的调试技巧:

  1. 使用console.log在关键位置输出变量值
  2. 结合断点和单步执行逐步跟踪代码
  3. 注意观察闭包中的变量,它们常常存储重要信息
  4. 对于混淆的代码,可以尝试用AST工具进行反混淆

5. 加密算法深度解析

5.1 HmacSHA512的工作原理

HmacSHA512是一种基于SHA-512哈希算法的消息认证码。它的特点是:

  1. 需要密钥和数据两个输入
  2. 通过特定的填充和迭代方式增强安全性
  3. 输出固定长度的512位(64字节)哈希值
  4. 即使输入微小变化,输出也会完全不同

在我们的案例中,网站开发者对标准HmacSHA512做了二次加工,取了其中部分字符作为最终结果。

5.2 自定义编码表的妙用

观察代码中的code_map,可以发现它有几个特点:

  1. 长度固定为20个字符
  2. 映射关系看似随机但其实是固定的
  3. 通过Unicode码取余的方式决定使用哪个字符
  4. 这种设计增加了逆向难度,因为需要同时知道映射表和算法

这种自定义编码表在Web安全中很常见,它相当于在标准加密算法外又加了一层保护。

6. 扩展应用与思考

6.1 如何应对算法变更

在实际项目中,网站可能会不定期更新加密算法。为了应对这种情况,可以:

  1. 定期检查加密是否仍然有效
  2. 建立自动化的算法检测机制
  3. 保留历史版本的处理逻辑
  4. 设计可插拔的加密模块

6.2 其他网站的类似加密

很多网站都采用了类似的动态请求头加密方案,常见的变化包括:

  1. 使用不同的哈希算法(如MD5、SHA256等)
  2. 添加时间戳或随机数作为盐值
  3. 多层加密嵌套
  4. 结合WebAssembly实现核心加密逻辑

掌握了这个案例的分析方法后,可以举一反三应用到其他网站的逆向工程中。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/20 5:37:21

复古CRT界面×流式输出|像素剧本圣殿TextIteratorStreamer实战

复古CRT界面流式输出|像素剧本圣殿TextIteratorStreamer实战 1. 项目概览 像素剧本圣殿(Pixel Script Temple)是一款专为剧本创作者设计的AI辅助工具,基于Qwen2.5-14B-Instruct大模型深度微调开发。这款工具最显著的特点是采用了…

作者头像 李华
网站建设 2026/6/20 5:36:04

用 AI Coding 工具生成 万字奇幻世界设定的实践记录雅

一、Actor 模型:不是并发技巧,而是领域单元 Actor 模型的本质是: Actor 是独立运行的实体 Actor 之间只通过消息交互 Actor 内部状态不可被外部直接访问 Actor 自行决定如何处理收到的消息 Actor 模型真正解决的是: 如何在不共享状…

作者头像 李华
网站建设 2026/6/2 12:54:50

从领域驱动到本体论:AI 时代的架构方法论变了崭

从0构建WAV文件:读懂计算机文件的本质 虽然接触计算机有一段时间了,但是我的视野一直局限于一个较小的范围之内,往往只能看到于算法竞赛相关的内容,计算机各种文件在我看来十分复杂,认为构建他们并能达到目的是一件困难…

作者头像 李华
网站建设 2026/4/14 2:06:22

ESP32-S3-wroom开发板在Arduino IDE中的完整配置指南(2024最新版)

ESP32-S3-WROOM开发板在Arduino IDE中的完整配置指南(2024最新版) 如果你刚接触ESP32-S3-WROOM开发板,想在Arduino IDE中快速搭建开发环境,这篇文章将带你从零开始完成所有配置。不同于网上零散的教程,我会结合2024年…

作者头像 李华
网站建设 2026/4/14 2:04:12

(三)FT2232HL高速调试器:从接口定义到OpenOCD配置优化的实战指南

1. FT2232HL调试器入门:硬件接口与功能解析 第一次拿到FT2232HL调试器时,我注意到这个巴掌大的设备竟然集成了JTAG和UART两大核心功能。作为嵌入式开发的老兵,我立刻意识到它的价值——通过单个USB接口就能实现双通道调试,这在调试…

作者头像 李华