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

张开发
2026/4/14 2:09:04 15 分钟阅读

分享文章

JS逆向实战:解密某查查网动态请求头的HmacSHA512加密
1. 从点击关注到发现加密参数最近在研究某查查网的关注功能时发现它的API请求头里有两个神秘的参数key和val。每次请求时这两个值都会变化明显是某种动态加密的结果。作为一个喜欢刨根问底的技术人我决定深入探究一下这个加密机制。打开Chrome开发者工具切换到Network面板勾选Preserve log选项。登录某查查网后随便搜索一家公司点击关注在XHR请求中果然看到了这个带着加密参数的请求。仔细观察发现这两个参数并不是简单的随机字符串而是有规律的加密结果。为了找到加密逻辑的源头我在XHR请求上设置了断点。点击关注按钮触发断点后通过Call Stack面板逐层向上追踪调用栈。这个过程就像侦探破案一样需要耐心地一层层排查。最终在某个异步回调函数中发现了关键线索 - 这里调用了f.request方法而加密参数的生成就在这个调用链中。2. 逆向分析加密逻辑2.1 定位关键加密函数通过断点调试我发现加密过程主要分为两个部分key的生成和val的生成。这两个值都使用了HmacSHA512加密算法但输入的参数有所不同。key的生成流程是这样的将API接口路径转换为小写将路径字符串重复拼接两次对每个字符的Unicode码进行特定运算通过一个固定的映射表生成中间密钥用这个密钥对API路径和请求体数据进行HmacSHA512加密最后取加密结果的第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中获取的每次页面加载都会变化。具体步骤拼接API路径、pathString、请求体数据和tid使用与key相同的密钥生成方法对拼接后的字符串进行HmacSHA512加密取完整加密结果作为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(), digestmodhashlib.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 codes3.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中。在实际应用中我们需要先访问网页获取这个值。可以通过以下方式使用requests库先请求首页用正则表达式或HTML解析器提取tid将tid用于后续的API请求import re import requests def get_tid(): response requests.get(https://www.qcc.com/) tid_match re.search(rwindow\.tid\s*\s*[\]([^\])[\], response.text) if tid_match: return tid_match.group(1) raise Exception(Failed to extract tid)4.2 处理动态变化的参数在实际使用中发现除了tid会变化外某些API的请求参数也可能包含时间戳或随机数。这就需要我们仔细分析每个API的请求参数识别哪些是固定值哪些是动态生成的对动态参数找到其生成规律或获取方式4.3 调试技巧分享在逆向过程中我总结了一些实用的调试技巧使用console.log在关键位置输出变量值结合断点和单步执行逐步跟踪代码注意观察闭包中的变量它们常常存储重要信息对于混淆的代码可以尝试用AST工具进行反混淆5. 加密算法深度解析5.1 HmacSHA512的工作原理HmacSHA512是一种基于SHA-512哈希算法的消息认证码。它的特点是需要密钥和数据两个输入通过特定的填充和迭代方式增强安全性输出固定长度的512位(64字节)哈希值即使输入微小变化输出也会完全不同在我们的案例中网站开发者对标准HmacSHA512做了二次加工取了其中部分字符作为最终结果。5.2 自定义编码表的妙用观察代码中的code_map可以发现它有几个特点长度固定为20个字符映射关系看似随机但其实是固定的通过Unicode码取余的方式决定使用哪个字符这种设计增加了逆向难度因为需要同时知道映射表和算法这种自定义编码表在Web安全中很常见它相当于在标准加密算法外又加了一层保护。6. 扩展应用与思考6.1 如何应对算法变更在实际项目中网站可能会不定期更新加密算法。为了应对这种情况可以定期检查加密是否仍然有效建立自动化的算法检测机制保留历史版本的处理逻辑设计可插拔的加密模块6.2 其他网站的类似加密很多网站都采用了类似的动态请求头加密方案常见的变化包括使用不同的哈希算法如MD5、SHA256等添加时间戳或随机数作为盐值多层加密嵌套结合WebAssembly实现核心加密逻辑掌握了这个案例的分析方法后可以举一反三应用到其他网站的逆向工程中。

更多文章