尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Web前端加密逆向全解析:从AES算法到JS混淆破解实战

Web前端加密逆向全解析:从AES算法到JS混淆破解实战 1. 项目概述一次对投标数据加密机制的深度探索最近在分析一个投标服务平台的客户端时遇到了一个挺有意思的挑战。这个平台在提交标书、获取项目详情等核心环节客户端与服务器之间的数据交互并非明文而是经过了一层自定义的加密处理。对于从事安全研究、数据合规审计或者单纯想理解其通信协议细节的开发者来说逆向分析这套加密机制就成了一个绕不开的课题。这不仅仅是“破解”更是一次对现代Web应用安全设计、前端混淆技术以及协议逆向方法的综合实践。通过这次分析我们不仅能搞清楚数据是如何被加密封装的更能深入理解在非开源环境下如何像解谜一样一步步还原出程序的完整逻辑。无论你是安全研究员、爬虫工程师还是对Web逆向感兴趣的前端开发者这个过程都能提供大量一手经验和实用技巧。2. 核心思路与技术选型2.1 逆向分析的目标与边界界定首先必须明确逆向工程的目标是理解而非破坏。我们的核心目标是厘清这个投标服务平台客户端的数据加密流程包括加密算法、密钥管理、数据封装格式等。这有助于进行安全评估、开发合规的数据对接接口或者进行学术研究。我们必须严格在法律和道德框架内操作仅针对自己拥有合法使用权的客户端程序进行分析绝不涉及对服务器端的未授权探测、干扰或数据窃取。基于这个目标我们的分析将聚焦于客户端通常是Web端JavaScript或桌面端如Electron应用。移动端AppAndroid/iOS原理类似但工具链不同。本次讨论将以最常见的Web端作为主要场景。2.2 主流工具链选型与理由工欲善其事必先利其器。Web逆向的经典工具组合如下浏览器开发者工具 (Chrome DevTools / Firefox Developer Tools)这是第一现场。主要用于网络抓包Network面板、动态调试Sources面板、监控函数调用Console面板以及查看内存中的对象。代码美化与格式化工具线上平台如beautifier.io或VS Code插件。被混淆压缩的JS代码通常是一行无法阅读。美化工具能还原出基本的代码结构缩进、换行是分析的起点。AST抽象语法树分析与反混淆工具对于使用了复杂混淆如Obfuscator.io, JavaScript Obfuscator的代码需要借助AST进行语义还原。常用工具有babel解析器、jsnice在线服务以及一些开源的反混淆脚本。它们能尝试将a[b]还原为a.b将0x1a2b还原为十进制等。本地调试代理 (Fiddler/Charles/Burp Suite)用于拦截和修改HTTPS流量重放请求测试加密函数。Burp Suite功能最全但Fiddler和Charles对HTTP/HTTPS流量抓取和修改更轻量便捷。Node.js 环境用于将关键加密函数从浏览器环境中剥离出来在本地独立运行和测试。这是验证分析结果、编写模拟代码的关键一步。注意关于“哪个AI可以分析IDA逆向”这个热词需要澄清一下。IDA Pro是主要用于原生二进制文件如Windows PE、Linux ELF逆向分析的静态反汇编工具在分析C/C、Delphi等编译型桌面客户端时是首选。对于Web JS逆向IDA并非主流工具。当前一些AI辅助编程工具如GitHub Copilot、Cursor或大语言模型如GPT-4、Claude可以在理解代码逻辑、解释复杂表达式时提供帮助但它们不能替代上述专业工具进行自动化逆向分析。它们更像是“高级搜索引擎”或“代码解释助手”帮你快速理解某段混淆代码可能的功能。3. 逆向分析全流程实操拆解3.1 第一步网络抓包与数据特征观察打开目标投标平台网站登录后进行关键操作例如“搜索项目”、“查看标书详情”或“提交投标文件”。同时打开浏览器开发者工具的Network面板并勾选“Preserve log”。重点关注类型为XHR或Fetch的请求。通常提交数据的POST请求和获取详情的POST/GET请求是加密的重灾区。点击一个请求查看其“Headers”、“Preview”和“Response”通常意义不大因为数据体可能已被加密。关键在于“Payload”或“Request”标签页。典型发现请求体 (Request Payload)不再是常见的JSON或Form Data而可能是一个看似随机的长字符串或者是一个结构体里包含一个data、encryptData、sign之类的字段其值是一串Base64编码的字符或十六进制字符串。请求头 (Headers)可能会包含一些额外信息如X-Encrypt-Mode: AESX-Timestamp 或者一个用于验证的X-Signature。这些是判断加密方式和密钥生成算法的重要线索。响应体 (Response)同样可能被加密返回的是一串密文。实操心得不要只看一个请求。对比同一个操作如翻页的多次请求观察哪些参数是变化的可能是时间戳、随机数哪些是固定的。变化的参数很可能参与了加密或签名过程。3.2 第二步定位前端加密入口点知道数据被加密了下一步是找到在浏览器中执行加密的JavaScript代码在哪里。有几种经典方法搜索关键词在开发者工具的Sources面板中对所有JS文件进行全局搜索CtrlShiftF。搜索关键词可以包括加密算法名如AES、RSA、encrypt、CryptoJS、请求体中的字段名如encryptData、甚至是一些可疑的常量字符串。如果代码混淆程度不高可能直接搜到相关函数。XHR/Fetch断点在Sources面板的“XHR/Fetch Breakpoints”里添加一个包含部分请求URL的断点。当发起该请求时代码执行会暂停此时调用栈Call Stack会显示出发起网络请求前的所有JavaScript函数逆向回溯就能找到加密函数。Hook关键函数在Console面板中注入代码劫持标准的XMLHttpRequest.send或fetch方法在数据发送前将其打印出来。也可以劫持常见的加密库函数如CryptoJS.AES.encrypt。// 示例Hook fetch 方法 let originalFetch window.fetch; window.fetch function(...args) { console.log(Fetch called with args:, args); // 重点查看 args[1]请求配置中的 body if (args[1] args[1].body) { console.log(Request Body:, args[1].body); } return originalFetch.apply(this, args); };执行加密操作观察Console输出就能在堆栈中看到加密函数的调用位置。常见问题如果代码被高度混淆函数名都变成了_0x1a2b3c这种形式搜索明文关键词可能失效。此时XHR断点和Hook方法是更可靠的选择。3.3 第三步静态分析与动态调试结合找到疑似加密函数后将其所在的JS文件保存到本地并用代码美化工具格式化。静态分析阅读代码寻找模式。典型的加密流程包括密钥生成可能由一个固定字符串盐加上时间戳、随机数等经过MD5、SHA256等哈希运算得到。加密过程调用CryptoJS.AES.encrypt(message, key, {mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7})或类似API。注意识别加密模式ECB, CBC、填充方式Pkcs7, ZeroPadding和初始向量IV。编码输出将加密后的二进制结果Cipher Object用Base64或Hex编码成字符串。动态调试在浏览器Sources面板中在加密函数的关键行设置断点。重新触发请求程序会在断点处暂停。此时你可以查看变量值将鼠标悬停在变量上或在Console中打印它们如console.log(key, iv, rawData)。单步执行 (F10/F11)一步步跟踪代码执行流程观察数据是如何一步步变化的。修改运行值在Scope面板中可以临时修改变量的值测试不同输入下的输出验证你的理解。实操心得遇到复杂的控制流混淆比如将代码逻辑拆分成无数个小函数通过一个调度器来调用可以尝试使用AST反混淆工具进行初步还原。但最根本的还是通过动态调试在内存中观察真实的输入和输出这比静态分析一堆乱码要直观得多。3.4 第四步算法还原与本地模拟当你确信已经找到了加密的核心函数假设叫encryptData(rawData)后下一步就是将它“剥离”出来在Node.js环境中复现。提取函数及其依赖加密函数不可能孤立存在。你需要将它以及它内部调用的所有子函数、引用的所有外部变量和对象可能是全局的也可能是某个闭包内的一并复制出来。如果使用了CryptoJS你需要在Node.js项目中安装crypto-js库。创建模拟环境在Node.js中你可能需要模拟浏览器中的一些环境比如window、document对象或者某些由平台注入的全局变量如_globalConfig。这些通常可以在浏览器控制台中通过输入变量名直接获取其值然后作为常量硬编码到你的Node.js脚本中。编写测试脚本// test_encrypt.js const CryptoJS require(crypto-js); // 如果用了CryptoJS // 粘贴你提取出来的所有加密相关函数 function generateKey(timestamp) { // ... 从浏览器中还原的逻辑 } function encryptData(rawData) { // ... 从浏览器中还原的核心逻辑 // 可能内部调用 generateKey, 使用 CryptoJS 等 } // 测试用例 const testPayload {page: 1, size: 20}; // 一个已知的明文 const testTimestamp 1678886400000; // 一个已知的时间戳 const encryptedResult encryptData(testPayload, testTimestamp); console.log(本地加密结果:, encryptedResult);验证结果将你的testPayload和testTimestamp在浏览器中触发相同的请求通过Hook或断点抓取到平台生成的密文。对比你的Node.js脚本输出结果与浏览器生成的密文是否完全一致。如果一致恭喜你算法还原成功。避坑技巧时间戳的精度毫秒/秒、密钥生成时字符串拼接的顺序、哈希输出的编码Hex/Base64、加密时IV的处理是固定值还是动态生成是否随密文一起传输——这些细节是导致还原失败的最常见原因。务必通过动态调试精确记录下每一个中间值进行比对。4. 投标平台加密方案深度解析4.1 典型加密架构猜想与验证基于对多个类似平台的分析其前端加密并非为了达到军事级安全而是为了增加自动化爬虫的难度、防止请求被轻易篡改、以及满足一些基本的传输安全要求。常见的架构如下对称加密AES为主绝大多数业务数据加密使用AES因为性能好。密钥Key和初始向量IV的动态生成是关键。非对称加密RSA可能用于密钥交换在登录环节或会话初始化时服务器可能会下发一个RSA公钥客户端用其加密一个随机生成的AES密钥会话密钥后再传给服务器。后续通信就用这个会话密钥进行AES加密。但在单次请求的加密中较少直接使用RSA加密业务数据因为性能差。签名机制防篡改除了加密往往还有签名。客户端将请求参数排序后拼接加上时间戳和某个固定盐值进行MD5或HMAC-SHA256运算得到签名sign。服务器收到后以同样算法验签确保数据在传输过程中未被修改。如何验证通过Hook或查看源代码寻找RSA、publicKey、encrypt与AES的encrypt区分、asymmetric等关键词可以判断是否使用了非对称加密。签名则通常寻找sign、md5、hmac、sort参数排序等函数调用。4.2 密钥管理策略分析密钥的安全性是加密的核心。在Web前端密钥无法绝对保密但可以通过动态性来增加破解成本。固定密钥最弱的方式密钥硬编码在JS中。通过搜索常量字符串或分析网络请求固定参数可能找到。时间戳/随机数派生密钥密钥 MD5(固定盐 当前时间戳)。时间戳通常从服务器响应或本地Date.now()获取并作为请求参数如t一同上传服务器端用同样算法即可还原密钥。逆向关键找到那个“固定盐”。会话密钥在登录后由服务器下发或协商产生存储在sessionStorage或内存中用于本次会话的所有请求。刷新页面或重新登录后失效。密钥混淆将真正的密钥拆分成多个部分分散在代码的不同位置运行时再组合。实操要点在动态调试时不要只关注加密函数的输入明文和输出密文。一定要在加密函数内部打印或记录下生成的**密钥Key和初始向量IV**的具体值。然后向上回溯看这个Key和IV是如何计算出来的。4.3 数据封装格式与完整流程还原一个完整的加密请求包可能不仅仅是密文。我们需要还原其整体封装格式。通过分析多个请求的Payload可以总结出类似如下的结构{ appId: xxxxxx, // 固定标识 timestamp: 1678886400000, // 当前毫秒时间戳 nonce: a1b2c3d4, // 随机字符串 data: U2FsdGVkX1/...Base64编码的AES密文, // 核心加密数据 sign: e10adc3949ba59abbe56e057f20f883e // 对前面所有字段按规则生成的签名 }完整流程还原步骤构造业务参数将用户操作转化为一个JSON对象如{projectId:123, page:1}。生成加密密钥根据当前时间戳timestamp和内置的盐salt通过MD5(salt timestamp)生成16字节的AES密钥key。IV可能是固定的也可能是密钥的一部分。加密业务数据将业务参数JSON字符串使用key和iv以AES-CBC-Pkcs7模式加密得到二进制密文然后进行Base64编码得到data字段。生成签名将所有待传参数如appId,timestamp,nonce,data按照键名字母序排序拼接成字符串rawSignStr然后计算MD5(rawSignStr anotherSalt)得到sign字段。发送请求将封装好的完整JSON对象作为请求体发送。你的Node.js模拟代码最终需要完整复现这个流程。5. 逆向过程中的疑难问题与解决方案5.1 高度混淆与反调试对抗现代Web应用会采用多种手段阻碍逆向代码混淆变量名混淆、控制流扁平化、字符串加密、僵尸代码插入。对策依赖AST反混淆工具进行初步清理但核心仍需动态调试。关注代码的“执行结果”而非“可读性”在内存中查看真实值。反调试检测开发者工具是否打开如果打开则跳入无限循环、停止执行关键代码或跳转到错误页面。对策使用setTimeout或Promise延迟调试器检测代码的执行。在开发者工具设置中禁用“停用断点”或“停用调试器”。使用无头浏览器如Puppeteer或修改过的浏览器进行自动化抓取绕过前端检测。环境检测检查navigator.userAgent、window对象下的某些属性如chrome、__driver_evaluate来判断是否处于自动化环境。对策在Node.js模拟或爬虫脚本中需要精心伪造这些环境变量使其与真实浏览器一致。5.2 加密函数依赖浏览器特有环境有时加密函数严重依赖浏览器环境例如使用了window.crypto.subtle这个Web Crypto API。依赖一个由服务器下发的、动态注入到页面全局变量中的密钥。函数被深度包裹在复杂的闭包和原型链中难以剥离。解决方案补环境在Node.js中使用jsdom或puppeteer库来模拟一个完整的浏览器窗口对象将缺失的API补全。直接调用浏览器对于极其复杂的情况可以放弃纯Node.js模拟转而使用Puppeteer或Selenium无头浏览器直接在浏览器环境中执行加密函数然后提取结果。这相当于将浏览器作为了一个“加密黑盒”来调用。const puppeteer require(puppeteer); async function getEncryptedData(rawData) { const browser await puppeteer.launch({headless: new}); const page await browser.newPage(); await page.goto(https://target-bidding-site.com); // 需要先加载包含加密逻辑的页面 // 在页面上下文中执行函数 const result await page.evaluate((data) { return window.__myEncryptFunction(data); // 假设加密函数在全局 }, rawData); await browser.close(); return result; }5.3 算法识别与参数确认即使找到了加密函数也可能因为混淆而无法直接认出是AES还是DES是CBC还是ECB模式。排查表特征可能算法密钥长度16字节 (128位), 24字节 (192位), 32字节 (256位)AES密钥长度8字节 (64位)DES函数调用中有mode: CBC,iv参数明显分组密码的CBC模式函数调用中有mode: ECB, 无iv参数分组密码的ECB模式输出密文长度与输入几乎成固定倍数关系如16字节对齐分组密码AES/DES输出为固定长度哈希值32字节十六进制SHA-256输出为固定长度哈希值16字节十六进制MD5确认方法在动态调试中构造一个短且固定的明文如123记录下加密结果。然后使用Python的pycryptodome库或在线加密工具用你猜测的算法、密钥和模式去加密同样的明文。如果结果一致则算法和参数得到确认。6. 从逆向分析到实际应用6.1 构建合规的数据采集工具成功逆向加密后你可以编写一个自动化的数据采集脚本。这个脚本应该模拟登录流程处理登录时的加密和验证码。在需要请求数据时按照还原的算法实时生成正确的加密参数和签名。处理服务器返回的可能也是加密的响应数据进行解密。遵守网站的robots.txt协议控制请求频率避免对服务器造成压力。注意事项此类工具仅可用于对公开数据或自己授权数据的合规采集与分析。大规模、高频次的请求可能触发网站的反爬机制IP封锁、账号封禁需要在代码中加入代理IP池、请求间隔、错误重试等策略。6.2 用于安全审计与漏洞挖掘逆向分析加密机制本身也是一次安全审计。你可以评估密钥强度密钥是否足够随机是否长期有效算法安全性是否使用了不安全的算法如DES、ECB模式实现漏洞是否存在逻辑漏洞比如签名可绕过、时间戳可被重放混淆有效性现有的混淆手段是否能有效阻止自动化攻击你的分析报告可以帮助平台方提升其安全性。当然任何漏洞发现都应通过合规渠道进行报告。6.3 理解业务逻辑与数据流转逆向的过程迫使你深入理解客户端与服务器的每一次交互细节。这对于开发与第三方平台对接的API中间件、进行数据迁移、或构建监控系统都大有裨益。你清楚地知道每一个参数的意义每一段数据的来源和去向这在处理复杂系统集成时是无价的经验。整个逆向分析就像一场与开发者隔空进行的智力游戏。它考验你的耐心、细心和对技术的综合运用能力。每一次成功还原出一个加密算法不仅解决了一个具体问题更极大地提升了你对Web应用安全架构的深层认知。记住工具和技术在迭代但“观察-假设-验证”的分析方法论是永恒的。保持好奇心严谨求证你就能解开大部分前端加密的黑盒。
返回列表