1. 初识Chrome开发者工具与前端加密每次遇到前端加密的登录表单时你是不是也头疼过明明用BurpSuite抓到了数据包却因为数据被加密成了一串乱码而无法进行后续测试。别急今天我们就用Chrome开发者工具F12这把瑞士军刀带你一步步拆解前端AES加密的黑盒子。先说说我最近遇到的一个真实案例某电商平台的登录接口提交的用户名和密码都变成了类似U2FsdGVkX13C7gT...的密文。常规的爆破手段瞬间失效但通过F12的Sources面板不到10分钟就找到了加密逻辑。你会发现前端加密就像魔术师的帽子——看似神秘一旦知道机关在哪一切都有迹可循。开发者工具的核心三板斧Elements面板查看DOM结构和绑定的事件监听器Sources面板调试JavaScript代码的作战指挥部Network面板监控所有网络请求的哨兵特别提醒新手朋友遇到加密别慌90%的网站用的都是标准加密库比如CryptoJS我们要做的只是找到密钥和调用方式。就像破解魔术不是要成为魔术师而是找出道具的隐藏机关。2. 定位加密函数的实战技巧2.1 从事件监听器顺藤摸瓜最近审计一个OA系统时发现登录按钮绑定了三个click事件。这时候不要蛮干教你个巧妙的方法在Elements面板选中登录按钮右侧Event Listeners选项卡会显示所有绑定事件。逐个点击右边的JS文件链接就像侦探翻看嫌疑人的档案。有个小技巧值得分享在可疑事件上右键选择Remove临时移除然后尝试提交表单。如果加密功能失效恭喜你找到了关键入口我在某次渗透测试中就用这个方法快速锁定了加密函数所在的loginHandler.js文件。2.2 全局搜索的妙用当代码量较大时试试CtrlShiftF全局搜索这些关键词encrypt AES CryptoJS mode/padding如CBC、PKCS7 key/iv密钥和初始化向量上周分析某金融平台时直接搜索CryptoJS.AES.encrypt就定位到了加密核心代码。记住优秀的猎人懂得使用工具——开发者工具的搜索支持正则表达式比如用encrypt.*\(.*\)可以快速找到所有加密函数定义。2.3 调用栈分析实战在Network面板找到登录请求右键选择Replay XHR会重新发送请求。这时立即切换到Sources面板点击右下角的{}美化代码格式然后在可疑位置打上断点。举个例子在某次测试中我在Network面板发现请求体有个encryptedData字段于是在Sources对所有包含这个字段名的JS文件设断点。当断点触发时Call Stack面板清晰显示了加密函数的调用路径login() - encryptPayload() - CryptoJS.AES.encrypt()。3. 提取加密参数的完整流程3.1 密钥提取的三种姿势硬编码密钥直接在代码里找到类似这样的定义const key 5tgbYHNUJM8ik,;动态生成密钥需要跟踪密钥生成函数。曾遇到一个网站用用户ID拼接时间戳再MD5哈希生成密钥这时就要在密钥生成函数处打条件断点。密钥协商最复杂的情况比如通过RSA交换AES密钥。这时要重点关注WebSocket通信或初始化接口的返回数据。3.2 解密AES配置参数标准的AES加密通常需要这些参数{ key: 1234567890abcdef, // 16/24/32字节长度 iv: abcdef1234567890, // 16字节初始化向量 mode: CryptoJS.mode.CBC, // 常见模式有ECB/CBC/CFB/OFB padding: CryptoJS.pad.Pkcs7 // 常见填充方式 }实测中发现80%的网站使用CBC模式Pkcs7填充。有个快速验证的方法在Console执行CryptoJS.AES然后按Tab键会自动补全可用方法和属性。4. 编写自动化测试脚本4.1 Python实现方案首先安装必备库pip install requests pycryptodome这里给出一个完整的AES加密模拟脚本from Crypto.Cipher import AES from Crypto.Util.Padding import pad import base64 def encrypt_aes(plaintext, key, iv): cipher AES.new(key.encode(), AES.MODE_CBC, iv.encode()) ciphertext cipher.encrypt(pad(plaintext.encode(), AES.block_size)) return base64.b64encode(ciphertext).decode() # 从F12提取的参数 key 5tgbYHNUJM8ik, iv abcdef1234567890 username admin password 123456 encrypted_creds encrypt_aes(f{{user:{username},pwd:{password}}}, key, iv) print(f加密结果: {encrypted_creds})4.2 直接调用JS函数对于复杂的加密逻辑可以用PyExecJS直接调用前端JS代码。把找到的加密函数保存为encrypt.jsfunction encryptData(data, key, iv) { // 这里是前端原始加密代码 return CryptoJS.AES.encrypt(data, key, {iv: iv}).toString(); }Python调用代码import execjs with open(encrypt.js, r, encodingutf-8) as f: ctx execjs.compile(f.read()) encrypted ctx.call(encryptData, 明文数据, 密钥, 初始化向量) print(encrypted)5. 高级调试技巧与坑点排查5.1 格式化混淆代码遇到压缩过的JS代码时点击Sources面板左下角的{}美化按钮。但要注意美化后的代码变量名可能仍然难以理解这时要重点关注以下几个特征调用CryptoJS相关方法的位置包含encrypt/decrypt字样的函数处理key/iv等参数的逻辑分支5.2 内存断点技巧对于动态生成的密钥可以在Console执行(function(){ let _key ; Object.defineProperty(window, secretKey, { set(v){ _keyv; debugger; }, get(){ return _key; } }); })();这段代码会在密钥被设置时自动触发断点我在分析某区块链网站时靠这个方法抓到了动态密钥。5.3 常见报错解决方案Invalid key length检查密钥是否是16/24/32字节Invalid IV lengthIV必须是16字节Padding error尝试更换padding模式如PKCS7改为ZeroPaddingUnicode编码问题确保所有字符串统一编码通常UTF-8记得去年遇到一个奇葩案例前端加密时先用Base64解码密钥字符串再用于AES加密。这种隐藏逻辑只有通过单步调试才能发现。6. 安全思考与防御建议虽然我们演示了如何逆向前端加密但要清醒认识到前端加密不能替代HTTPS等传输层安全措施。它的主要价值在于增加自动化攻击门槛防止请求被直接重放避免敏感信息明文出现在日志中对开发者的建议避免将主密钥硬编码在前端代码中考虑使用Web Crypto API替代第三方加密库为每个会话生成临时密钥配合使用HMAC进行完整性校验某次安全评估中发现有个系统虽然用了AES加密但密钥居然是password123。这种安全防护反而会给人虚假的安全感。