一、引言:为什么JS加密成为爬虫的最大障碍
在当今的Web开发中,前端JavaScript加密已成为保护数据的重要手段。传统的反爬手段如User-Agent检测、IP限制、Cookie验证等,已经被爬虫工程师研究得非常透彻,很容易被绕过。而JS加密反爬则将关键的参数生成逻辑放在客户端执行,服务器只验证加密后的结果,这大大增加了爬虫的难度。
具体来说,JS加密反爬具有以下优势:
- 加密逻辑动态变化,难以一次性破解
- 每个请求都需要生成唯一的加密参数
- 可以结合时间戳、随机数等防止重放攻击
- 混淆后的JS代码可读性极差,增加分析成本
对于爬虫开发者来说,理解和破解这些加密机制已经成为一项必备技能。本文将系统介绍JS加密破解的完整方法论,从原理到实战,帮助读者掌握这一关键技术。
值得一提的是,像 https://rebang.open2hub.com/ 这样的热榜聚合平台,同样可能采用JS加密手段来保护其数据接口。了解JS加密的破解方法,对于爬取此类平台的数据具有重要的实践意义。
二、JS加密的核心原理与常见类型
2.1 为什么网站使用JS加密反爬
JS加密的核心思想是:将关键的请求参数(如签名、令牌等)的生成逻辑放在前端JavaScript中执行,服务器端只负责验证加密后的结果是否正确。这样一来,爬虫如果想模拟合法请求,就必须破解前端的加密逻辑,而前端代码虽然公开可见,但可以通过混淆、压缩等手段大幅增加分析难度。
2.2 常见的JS加密类型
目前主流的JS加密可以分为以下几类:
| 加密类型 | 代表算法 | 特点 | 常见应用场景 |
|---|---|---|---|
| 哈希加密 | MD5、SHA1、SHA256 | 单向不可逆,相同输入产生相同输出 | 生成签名、校验数据完整性 |
| 对称加密 | AES、DES、3DES | 加密解密使用相同密钥,速度快 | 加密请求体、响应体 |
| 非对称加密 | RSA | 公钥加密私钥解密,安全性高 | 传输对称密钥、登录密码加密 |
| 自定义加密 | 网站自行实现的算法 | 无标准可循,破解难度最大 | 生成关键请求参数如sign、token |
2.3 JS混淆技术
混淆与加密不同------混淆后的代码虽然可正常执行,但可读性完全丧失,即便通过代码格式化工具处理,也难以梳理出清晰的逻辑脉络。常见的JS混淆手段包括:
变量与函数名混淆 :将具有语义化的变量名(如getSignature、aesEncrypt、secretKey)替换为_0x1a2b、_0xf3e等无意义的十六进制字符,彻底破坏代码的语义关联性。
控制流扁平化:通过switch/while循环嵌套、跳转语句重构,打乱原始代码的执行顺序,将线性逻辑拆解为碎片化分支,增加逻辑追踪难度。
字符串加密:将明文密钥、接口参数、URL路径等关键信息通过Base64、十六进制等方式加密,再通过内置函数动态解密。
反调试机制:嵌入调试检测代码,当检测到开发者工具开启、断点调试等操作时,触发死循环、页面刷新等逻辑。
代码压缩与合并:删除空格、换行、注释,将多个JS文件合并为单文件并压缩为一行。
2.4 Webpack打包加密
Webpack打包加密是主流网站常用的防护手段------它通过模块混淆、变量压缩、动态加载等方式,让爬虫工程师难以定位核心请求逻辑。其核心手段包括:
- 模块碎片化打包:将JS代码拆分为多个chunk(代码块),核心加密逻辑单独打包成独立模块
- 动态注入与执行 :部分加密逻辑通过
eval、new Function等方式动态生成代码并执行
2.5 JSVMP(JavaScript虚拟机保护)
JSVMP是一种更高级的保护技术,它将原始JavaScript代码编译为自定义的字节码,这些字节码由操作码和操作数组成,只能由特定的解释器执行。其原理是把JS代码通过词法分析转化为AST抽象语法树,然后由AST生成自定义指令数组,再交由自实现的解释器执行。主流内容平台通过JSVMP技术构建动态防御体系,其核心特征包括:
- 多层加密架构:采用AES-256与RSA混合加密,结合动态密钥生成机制
- 运行时环境隔离:通过WebAssembly实现关键逻辑的沙箱化执行
- 行为指纹追踪:集成Canvas指纹、WebGL渲染特征等10+维度设备识别
- 反调试对抗:自动检测开发者工具开启状态,触发数据污染机制
三、JS加密破解的完整流程
破解JS参数加密是一个系统性的过程,需要遵循一定的步骤和方法。
3.1 抓包分析与参数识别
破解的第一步是使用抓包工具分析网站的请求。推荐使用Chrome浏览器自带的开发者工具(F12)。
具体操作步骤:
- 打开Chrome开发者工具,切换到"Network"面板
- 勾选"Preserve log"选项,防止页面刷新时日志丢失
- 刷新页面或触发目标操作
- 找到对应的API请求,查看"Request Headers"和"Form Data"
- 识别出哪些参数是加密的,通常命名为sign、token、signature、_sign等
关键技巧:对比多次请求的参数,找出变化的参数。不变的参数通常不需要处理,而变化的参数就是需要破解的目标。
3.2 定位加密函数位置
找到加密参数后,下一步就是定位生成这些参数的JS函数。
方法一:全局搜索关键词
在Chrome开发者工具的"Sources"面板中,使用快捷键Ctrl+Shift+F打开全局搜索,搜索加密参数的名称。例如,如果加密参数是"sign",就搜索"sign="、"sign:"、"sign("等。
方法二:XHR断点
如果加密参数是在AJAX请求中发送的,可以使用XHR断点来定位。在"Sources"面板的"XHR/fetch Breakpoints"中添加断点,输入API请求的部分URL。当请求发送时,代码会在发送前中断,此时可以查看调用栈,找到加密函数的位置。
方法三:调用栈追踪
通过Network请求的Initiator标签回溯加密逻辑触发点。
方法四:事件断点
如果加密参数是在点击按钮等事件触发时生成的,可以使用事件断点。
3.3 调试分析技巧
定位到加密函数后,需要进行深入的调试分析:
代码格式化 :点击Sources面板左下角的{}按钮美化压缩代码,提升可读性。
断点类型:
- XHR断点:针对特定URL拦截请求
- 事件断点:监听click、submit等DOM事件
- 条件断点:在加密函数内设置Conditional Breakpoint
Scope面板:查看局部变量、闭包域中的关键值(如密钥、盐值)。
3.4 反调试对抗
针对常见的反调试技术,需实施以下对策:
无限debugger绕过:在debugger对应行号右键点击"一律不在此处暂停",或添加条件断点填入false条件。
Hook注入:针对页面的反调试机制,使用hook注入方法绕过debugger断点。
调试器检测绕过 :重写window.outerWidth等检测属性。
使用油猴插件:随手写个脚本替换网站JS文件,立刻让无限Debugger和反爬弹窗消失。
3.5 代码反混淆
混淆后的JS代码需要通过反混淆工具还原可读性。
AST解混淆 :使用Esprima解析代码的抽象语法树,把a[0x12b]=b['xYz']这种"天书"还原成cookie.token = user.id。
在线反混淆工具:JSNice可以一键给混淆变量自动重命名;De4js网页版粘贴混淆代码,30秒输出可读版本。
本地反混淆:推荐Babel插件魔改AST,实现深度反混淆。
3.6 模拟执行方案
分析完加密逻辑后,需要在爬虫中模拟执行。
方案一:扣JS代码 + execjs调用
对于逻辑简单、无环境依赖的场景,可以将加密JS代码扣取出来,通过Python的execjs库调用执行。
python
import execjs
with open('encrypt.js', 'r', encoding='utf-8') as f:
js_code = f.read()
ctx = execjs.compile(js_code)
encrypted = ctx.call('encrypt_function', 'input_data')
方案二:RPC通信
对于复杂混淆或浏览器环境依赖的场景,可以使用Sekiro等工具进行RPC通信。
方案三:无头浏览器
对于需要完整渲染流程的场景,可以使用PlayWright或Selenium。
四、核心工具链
4.1 浏览器调试工具
Chrome开发者工具(Sources面板) :核心用于定位混淆JS文件、断点调试、监控网络请求。
定制版Chrome DevTools:移除安全限制,便于深度调试。
4.2 动态分析工具
Frida:逆向圈的"瑞士军刀",用几行脚本就能Hook住关键函数,实时查看参数、篡改返回值。
油猴插件(Tampermonkey) :可以注入脚本监听关键函数(如btoa、encrypt)。
4.3 反混淆工具
AST Explorer:在线解析和操作抽象语法树。
JsBeautifier:对混淆压缩后的JS代码进行格式化。
De4js:在线反混淆工具,粘贴代码即可输出可读版本。
Babel:本地AST操作框架,可实现深度反混淆。
4.4 Python调用工具
PyExecJS:把抠出来的JS加密代码塞进Python,调用Node.js环境执行。
V8引擎沙箱(pyv8/bestV8) :直接运行高危代码,即便遇到while(true){debugger}死循环也不怕崩进程。
4.5 抓包工具
Fiddler Classic:开启HTTPS解密后,所有API请求参数尽收眼底。
curl_cffi:对抗JA3指纹的终极武器,用Python模拟浏览器TLS指纹。
五、实战案例解析
5.1 案例一:MD5加密参数破解(以汽车之家登录为例)
目标:登录请求中的pwd参数为MD5加密。
逆向步骤:
- 在Sources搜索"pwd",定位到login.js文件
- 发现关键函数
hex_md5(s) - 扣取完整MD5相关函数(core_md5, binl2hex, str2binl)
- Python通过execjs调用:
python
import execjs
with open('qichezhijia.js', 'r', encoding='utf-8') as f:
js_code = f.read()
ctx = execjs.compile(js_code)
encrypted_pwd = ctx.call('hex_md5', '123456')
# 输出:d6d7d5a8c4e6e7b8
5.2 案例二:Webpack加密逆向
Webpack打包后的JS通常是压缩混淆状态,逆向步骤包括:
步骤1:定位Webpack加密入口
打开Chrome DevTools,切换到Network面板,筛选"JS"类型请求。找到命名含hash的"主JS文件"(通常Size最大,且加载顺序靠前,如main.8a7b6c.js)。
步骤2:反混淆初处理
在DevTools中格式化代码。
步骤3:定位加载器
Webpack必有一个加载模块的方法(call或apply),找到加载器先抠出来。
步骤4:扣取加密方法
定位并扣取调用的加密方法,导出加密方法。
5.3 案例三:JSVMP逆向
JSVMP逆向的难点在于代码被转换为自定义字节码并由虚拟机执行。
破解思路:
- 入口点定位:通过XHR断点捕获初始请求
- 调用栈分析 :使用
performance.getEntries()追踪脚本加载顺序 - 内存转储:在关键加密函数执行前后进行堆快照对比
- WebAssembly逆向:使用WABT工具链反编译wasm模块
某头部短视频平台2025年的签名参数生成涉及32层逻辑嵌套,包含非对称加密、哈希链、时间窗口校验等复合机制。
六、高级技术:AST在代码还原中的核心应用
AST(Abstract Syntax Tree,抽象语法树)是目前爬虫领域的热点技术。通过AST可以对混淆代码进行语法分析,批量还原变量名、简化控制流。
6.1 AST的工作原理
AST将源代码解析为树状结构,每个节点代表代码中的一个语法结构。通过操作这棵树,可以实现代码的自动化还原。
6.2 AST的典型应用场景
变量名还原 :将混淆的_0x1a2b、_0xf3e等变量名还原为有语义的名称。
控制流简化:将switch/while嵌套的控制流平坦化结构还原为线性逻辑。
字符串解密:将加密的字符串批量解密为明文。
6.3 AST工具链
AST Explorer(https://astexplorer.net/):在线解析和操作AST,支持多种语言和编译器。
Acorn/Esprima:JavaScript的AST解析器。
Babel:完整的AST操作框架,支持代码的解析、转换和生成。
七、法律与伦理边界
7.1 爬虫的法律风险
网络爬虫作为中立技术不能突破刑法的边界。并非所有使用爬虫技术获取数据的行为均系合法行为,是否构成犯罪要看是否属于刑法意义上的危害行为。
司法实践中,突破加密验证、伪造请求的行为,即便抓取部分公开信息,仍可能被认定为非法获取计算机信息系统数据。
7.2 合规要点
爬虫的合法性可以概括为:
数据来源合法 + 技术手段合法 + 用途合法
数据来源合法:爬取的数据应为公开数据,不应突破访问权限获取非公开数据。
技术手段合法:不应通过破解加密、伪造请求等方式突破网站的技术防护措施。
用途合法:爬取的数据应用于合法目的,不应用于商业牟利或破坏市场秩序。
7.3 合规建议
- 尊重robots.txt协议:遵守网站的爬虫协议
- 控制请求频率:避免高频请求对网站服务器造成负担
- 仅限技术研究:JS逆向技术应限于研究加密算法与安全机制
- 咨询法律团队:当涉及商业用途或大规模爬取时,务必咨询法律团队
八、总结与展望
JS加密破解是一个系统工程,需要综合运用抓包分析、代码调试、反混淆、模拟执行等多种技术手段。随着网站防护技术的不断升级,爬虫开发者也需要持续学习和更新知识储备。
从简单的MD5哈希到复杂的AES对称加密,再到高度混淆的自定义算法和JSVMP虚拟机保护,JS加密技术正在变得越来越复杂。面对这些挑战,爬虫开发者需要:
- 掌握Chrome调试等基础技能
- 熟悉AST等高级代码还原技术
- 了解WebAssembly等新兴防护机制的逆向方法
- 保持对反调试、反混淆等对抗技术的敏感度
同时,在开展JS逆向工作时,必须时刻牢记法律与伦理的边界,将技术能力用于正当的研究和学习目的,而非非法获取数据或破坏他人系统。