百度翻译#js逆向#2024:从sign参数破解到完整Python调用实战

📅 2026/7/16 5:18:34
百度翻译#js逆向#2024:从sign参数破解到完整Python调用实战
1. 百度翻译JS逆向的核心挑战百度翻译作为国内领先的机器翻译服务其前端采用了多重防护机制来保护核心接口。2024年的最新版本中sign参数的生成逻辑变得更加复杂这对逆向工程提出了新的挑战。我最近在调试时发现新版百度翻译的加密逻辑至少包含三层嵌套函数调用而且加入了环境检测机制。最让人头疼的是那个动态变化的token参数。记得有一次调试时我花了整整三个小时才定位到token的生成位置——它居然藏在某个被压缩到单行的eval函数里。不过别担心接下来我会带你一步步破解这些难题。2. 准备工作与环境搭建2.1 必备工具清单工欲善其事必先利其器。在开始逆向之前你需要准备好以下工具Chrome浏览器最新版开发者工具是我们的主战场Fiddler/Charles用于抓包分析网络请求VS Code编辑JS和Python代码Node.js环境本地执行JS代码测试Python 3.8最终实现调用的语言环境我建议先创建一个干净的Python虚拟环境python -m venv baidu_fanyi source baidu_fanyi/bin/activate # Linux/Mac baidu_fanyi\Scripts\activate # Windows2.2 关键Python库安装这些库会在后续步骤中用到pip install requests execjs pyexecjs json5特别提醒如果你在Windows上遇到execjs报错可能需要安装Node.js并确保它在系统PATH中。我在Windows 11上实测时就因为这个坑浪费了半小时。3. 动态调试与参数定位3.1 抓包分析关键请求打开Chrome开发者工具F12切换到Network面板勾选Preserve log。在百度翻译页面输入要翻译的内容后你会看到一堆网络请求。重点关注名字包含v2transapi的POST请求。这是我最近抓到的典型请求参数from: en to: zh query: hello transtype: translang simple_means_flag: 3 sign: 891234.562341 token: 8a7b6c5d4e3f2g1h domain: common3.2 定位sign生成函数在开发者工具的Sources面板按CtrlShiftF全局搜索sign:。你会看到类似这样的代码片段sign: y(n),点击进入这个y函数你会发现它可能被重命名了比如变成_0x1a2b3c这样的名字。这就是我们需要破解的核心加密函数。我最近一次分析时发现2024版的sign生成函数开头多了这样的环境检测代码if(typeof window._$jsaprt ! undefined){ throw new Error(Debugger detected); }4. 逆向破解sign参数4.1 关键加密逻辑分析经过多次调试我发现sign参数的生成主要依赖以下要素待翻译文本query一个固定值320305.1313212012024年仍然有效复杂的位运算和字符串操作核心加密函数通常包含这样的结构function e(r) { var o r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g); if (null o) { var t r.length; t 30 (r r.substr(0, 10) r.substr(Math.floor(t / 2) - 5, 10) r.substr(-10, 10)) } // ...更多加密逻辑 }4.2 补全缺失的JS环境在本地执行这些JS代码时经常会遇到xxx is not defined的错误。这是因为浏览器环境中有些内置变量在Node.js中不存在。我们需要补全这些环境// 在JS文件开头添加这些补丁 var window { gtk: 320305.131321201 }; var navigator { userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 };5. Python完整调用实现5.1 封装JS执行环境首先把完整的加密JS保存为baidu_fanyi.js然后通过Python调用import execjs import json5 import requests def get_sign(word): with open(baidu_fanyi.js, r, encodingutf-8) as f: js_code f.read() ctx execjs.compile(js_code) return ctx.call(e, word) # e是加密函数名5.2 获取动态tokentoken可以通过正则表达式从页面HTML中提取def get_token(): url https://fanyi.baidu.com headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 } resp requests.get(url, headersheaders) token re.search(rtoken: ([0-9a-z]), resp.text).group(1) return token5.3 完整调用示例def translate(word, from_langen, to_langzh): url https://fanyi.baidu.com/v2transapi headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36, Cookie: 你的百度Cookie, # 可选 Referer: https://fanyi.baidu.com/ } data { from: from_lang, to: to_lang, query: word, transtype: translang, simple_means_flag: 3, sign: get_sign(word), token: get_token(), domain: common } resp requests.post(url, headersheaders, datadata) result json5.loads(resp.text) return result[trans_result][data][0][dst]6. 常见问题与解决方案6.1 请求返回403错误这通常是因为缺少必要的请求头。除了User-Agent2024年新版还需要带上RefererX-Requested-With: XMLHttpRequestOrigin: https://fanyi.baidu.com6.2 sign验证失败可能的原因包括JS代码中环境变量未补全待翻译文本处理逻辑有差异百度更新了加密算法解决方案是重新调试JS确认每个步骤的输出是否与浏览器中一致。我建议在关键位置添加console.log输出方便比对。6.3 执行速度优化当需要批量翻译时原始方案性能可能不够理想。可以考虑预编译JS代码复用execjs上下文使用多线程/协程优化后的代码示例# 预编译JS ctx execjs.compile(open(baidu_fanyi.js).read()) def fast_translate(word): sign ctx.call(e, word) # ...其余代码不变7. 进阶技巧与最新变化2024年第二季度百度翻译又进行了一次安全升级新增了以下防护措施动态加载核心加密函数增加了鼠标移动轨迹检测对高频请求实施了更严格的限流应对策略包括使用Puppeteer等无头浏览器模拟真实用户行为在请求间添加随机延迟轮换IP地址和User-Agent这里分享一个我最近发现的技巧百度翻译现在会检测execjs的执行环境可以通过修改JS代码开头来绕过检测// 在JS文件最前面添加 Object.defineProperty(navigator, webdriver, {get: () false});8. 完整项目结构建议对于长期维护的项目我推荐这样的目录结构baidu_fanyi/ ├── core/ │ ├── __init__.py │ ├── decrypt.py # 加密解密逻辑 │ └── api.py # 接口调用 ├── js/ │ └── baidu_v2.js # 加密JS代码 ├── tests/ # 测试用例 ├── utils/ # 工具函数 └── main.py # 入口文件这种结构方便后续维护和扩展比如添加其他翻译平台的逆向实现。在实际使用中我发现百度翻译的接口稳定性很大程度上取决于请求头的完整性和Cookie的有效性。如果遇到突然失效的情况首先检查这些基础配置往往能节省大量调试时间。