ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

某眼票房API逆向分析:signKey与mygsig参数生成机制

2026/8/13 4:23:33 拓冰建站 浏览量
某眼票房API逆向分析:signKey与mygsig参数生成机制 1. 项目概述某眼票房数据逆向分析实战最近在研究电影票房数据的获取方式发现某眼平台的API请求中有两个关键参数signKey和mygsig这显然是用于请求验证的签名参数。作为一名爬虫开发者我决定深入分析这两个参数的生成逻辑。通过逆向工程我们不仅能理解其加密机制还能为后续的数据采集工作打下基础。这个逆向过程涉及JavaScript代码分析、加密算法识别和混淆代码处理等技术点。特别值得注意的是平台使用了ob混淆技术来增加逆向难度这也是当前Web逆向中常见的防护手段。下面我将详细记录整个分析过程包括工具选择、关键步骤和踩坑经验。2. 核心工具与环境准备2.1 基础工具链配置逆向工程需要一套完整的工具链支持以下是我在实际工作中验证过的工具组合浏览器开发者工具Chrome DevTools是最基础的调试工具特别是其中的Network面板和Sources面板抓包工具Charles或Fiddler用于捕获HTTPS请求需要配置SSL证书逆向专用浏览器使用定制版Chromium如X浏览器可绕过部分反调试机制代码美化工具Prettier或在线JS美化工具处理压缩代码哈希计算工具HashCalc用于快速验证MD5等哈希值提示建议准备一个干净的虚拟机环境因为逆向过程中可能会触发网站的反爬机制导致IP被封禁。2.2 JavaScript逆向专项工具针对JS逆向的特殊需求还需要以下工具# Node.js环境用于运行和测试提取的加密函数 npm install crypto-js vm2 # 安卓逆向工具包如需处理APP端加密 adb toolkit apktool对于ob混淆代码的处理AST抽象语法树分析是最有效的方法。可以使用babel-parser等工具进行自动化分析const parser require(babel/parser); const traverse require(babel/traverse).default; const code 混淆后的JS代码; const ast parser.parse(code);3. 参数定位与初步分析3.1 请求参数抓取首先通过浏览器开发者工具捕获正常请求观察包含signKey和mygsig参数的请求GET /api/boxoffice?param1value1param2value2signKey4f5d6a7b8c9d0e1fmygsiga1b2c3d4e5关键发现这两个参数都是32位十六进制字符串符合MD5哈希的特征参数值每次请求都会变化说明包含动态因素缺失参数时返回403错误验证了其鉴权作用3.2 加密入口定位在Sources面板中搜索关键词signKey和mygsig很快在压缩的JS文件中发现相关代码片段function generateSign(params) { var t new Date().getTime(); var e Object.keys(params).sort().map(function(key) { return key params[key] }).join(); return md5(e t 固定盐值).substr(8, 32); }这段代码虽然经过压缩但已经揭示了基本的签名生成逻辑获取当前时间戳对请求参数按键名排序并拼接拼接时间戳和固定盐值计算MD5并截取部分作为最终签名4. 深入逆向ob混淆代码4.1 ob混淆特征识别某眼平台使用了obfuscator.io进行的代码混淆具有以下特征变量名替换为十六进制字符串如_0x1a2b3c字符串常量被编码为Unicode或base64插入大量无用代码和控制流混淆关键函数被分散到不同位置典型的混淆代码结构var _0x3d8a [\x48\x65\x6c\x6c\x6f, \x57\x6f\x72\x6c\x64]; function _0x12ab(_0x3d8a12, _0x12ab34) { return _0x3d8a[_0x3d8a12]; }4.2 反混淆实战步骤通过AST解析和代码重构我总结出以下反混淆流程字符串常量还原将编码的字符串转换为可读形式变量名重命名根据上下文语义重命名变量控制流平坦化处理识别并简化混淆的控制结构无用代码删除移除不影响逻辑的冗余代码实际操作中的技巧使用babel-generator将AST重新生成为可读代码对高频出现的函数进行单独分析和命名通过console.log输出中间值验证理解是否正确4.3 关键加密函数还原经过反混淆处理后关键的签名生成函数如下function generateSignature(params, timestamp, secret) { // 1. 参数排序 const sortedKeys Object.keys(params).sort(); // 2. 键值拼接 let paramString ; sortedKeys.forEach(key { paramString ${key}${params[key]}; }); paramString paramString.slice(0, -1); // 移除末尾的 // 3. 拼接时间戳和密钥 const rawSignString ${paramString}t${timestamp}key${secret}; // 4. 计算MD5并截取 const fullMD5 CryptoJS.MD5(rawSignString).toString(); return fullMD5.substring(8, 24); // 取中间16位 }5. 签名算法完整解析5.1 signKey生成机制通过逆向分析确认signKey的生成逻辑如下输入参数请求参数对象如{cityId: 1, date: 2023-05-01}当前时间戳精确到秒固定盐值通过分析多个请求确定为maoyan#2023生成步骤将参数按键名升序排列拼接为key1value1key2value2格式的字符串追加时间戳和盐值paramString t timestamp key secret计算完整字符串的MD5值取第9-24位字符16位长度作为最终signKey5.2 mygsig参数分析mygsig参数比signKey更为复杂经过深入分析发现它实际上是双重加密的结果第一层加密使用SHA256算法第二层对结果再次进行MD5计算最终截取第1-16位作为mygsig值核心代码逻辑function generateMygsig(params, deviceId) { // 第一层SHA256 const sha256Str CryptoJS.SHA256( JSON.stringify(params) deviceId ).toString(); // 第二层MD5 const md5Str CryptoJS.MD5(sha256Str).toString(); return md5Str.substring(0, 16); }5.3 时间戳处理细节时间戳的处理有几个关键点需要注意服务器允许的时间偏差为±300秒时间戳单位为秒不是毫秒在移动端APP中时间戳还会与设备信息绑定部分接口要求时间戳必须单调递增实际应用中建议// 获取符合要求的时间戳 function getValidTimestamp(lastTimestamp) { let ts Math.floor(Date.now() / 1000); if (lastTimestamp ts lastTimestamp) { ts lastTimestamp 1; } return ts; }6. 完整请求构造示例6.1 基础请求参数假设我们要获取2023年5月1日北京市的票房数据const params { cityId: 1, date: 2023-05-01, type: day };6.2 签名计算实现基于前面的分析完整的签名计算代码如下const CryptoJS require(crypto-js); function generateSignatures(params) { const timestamp Math.floor(Date.now() / 1000); const secret maoyan#2023; const deviceId default_device_id; // 生成signKey const sortedKeys Object.keys(params).sort(); const paramString sortedKeys.map(k ${k}${params[k]}).join(); const signKeyRaw ${paramString}t${timestamp}key${secret}; const signKey CryptoJS.MD5(signKeyRaw).toString().substr(8, 16); // 生成mygsig const sha256Str CryptoJS.SHA256( JSON.stringify(params) deviceId ).toString(); const mygsig CryptoJS.MD5(sha256Str).toString().substr(0, 16); return { signKey, mygsig, timestamp }; }6.3 最终请求示例const { signKey, mygsig, timestamp } generateSignatures(params); const requestUrl https://piaofang.maoyan.com/api/boxoffice?cityId1date2023-05-01typedayt${timestamp}signKey${signKey}mygsig${mygsig}; console.log(requestUrl);7. 常见问题与解决方案7.1 签名验证失败的可能原因在实际测试中可能会遇到签名无效的情况常见原因包括时间戳不同步服务器时间与本地时间偏差超过5分钟解决方案同步网络时间或从服务器获取基准时间参数顺序错误键名排序不符合要求验证确保使用ASCII码升序排列盐值更新平台可能定期更换固定盐值检测通过对比多个请求分析新盐值模式设备指纹绑定APP端请求可能需要有效设备ID处理捕获真实设备请求提取合法deviceId7.2 反爬机制应对策略某眼平台采用了多种反爬措施请求频率限制单个IP每分钟不超过30次请求解决方案使用代理IP池并控制请求间隔行为验证异常流量会触发验证码预防模拟正常用户操作间隔和鼠标移动轨迹TLS指纹识别检测非浏览器流量绕过使用真实浏览器或修改TLS指纹环境检测检查navigator等浏览器属性对策完善爬虫的浏览器指纹模拟7.3 性能优化建议当需要大规模采集数据时可以考虑以下优化签名计算缓存对于相同参数的请求签名可以复用在有效期内预生成时间戳批量生成符合要求的时间戳序列WebAssembly加速将核心加密算法移植到WASM执行分布式计算将签名计算任务分发到多个worker线程示例代码// 使用Worker线程池处理签名计算 const { Worker, isMainThread, workerData } require(worker_threads); if (isMainThread) { // 主线程分发任务 const worker new Worker(__filename, { workerData: { params: {...} } }); } else { // 工作线程执行计算 const { params } workerData; const signatures generateSignatures(params); parentPort.postMessage(signatures); }8. 进阶动态盐值分析在长期监测中发现平台在某些情况下会使用动态盐值。通过Hook关键函数可以捕获盐值生成逻辑// 使用Proxy监控参数对象 const proxiedParams new Proxy(params, { get(target, prop) { if (prop secret) { console.trace(Secret accessed); } return target[prop]; } }); // 或者Hook加密函数 const originalMD5 CryptoJS.MD5; CryptoJS.MD5 function(input) { console.log(MD5 input:, input); return originalMD5(input); };动态盐值通常有以下几种生成方式基于日期的变化如每日更换从服务器获取的临时token用户会话相关的信息派生请求特定参数组合的哈希值应对策略包括建立盐值字典并自动更新实现盐值预测算法定期从官方APP捕获新盐值9. 法律与合规考量在进行任何逆向工程前必须考虑法律风险数据使用条款仔细阅读平台的服务条款明确数据使用限制合理使用原则控制请求频率避免影响正常服务数据脱敏对采集的数据进行适当处理移除个人信息商业用途限制部分数据可能禁止用于商业分析建议措施设置合理的爬取间隔如每分钟不超过10次请求仅采集必要的公开数据在用户代理中明确标识爬虫身份考虑使用官方API如有提供10. 其他相关技术扩展10.1 移动端APP逆向如果从Web端难以获取足够数据可以考虑分析移动端APP安卓APK逆向流程使用apktool解包APK文件分析smali代码或使用dex2jar转换为Java代码定位网络请求相关代码提取加密参数生成逻辑iOS逆向工具链使用frida进行动态注入通过Cycript调试运行时对象使用class-dump导出头文件10.2 协议逆向工程方法论系统化的逆向工程应该遵循以下步骤接口枚举收集所有可能的API端点参数分类区分静态参数和动态参数依赖分析确定参数间的依赖关系代码定位查找关键函数实现算法还原理解并重建核心逻辑模拟验证独立实现验证正确性10.3 自动化逆向框架对于频繁变化的加密逻辑可以考虑构建自动化监测系统变更检测定期检查签名参数模式变化逻辑比对自动分析新旧版本代码差异测试验证自动化测试用例验证采集效果报警机制签名失败时触发人工分析示例架构采集器 → 签名服务 → 验证模块 → 数据存储 ↑ 自动更新机制通过这次对某眼票房API的逆向分析我深刻体会到现代Web应用安全机制的复杂性。从简单的MD5参数到复杂的ob混淆代码平台方在不断升级防护措施。作为开发者我们需要在技术探索和合规使用之间找到平衡点。在实际项目中建议优先考虑官方API合作渠道逆向分析仅作为技术研究和应急方案。