上周帮朋友排查一个App登录失败的问题,抓包发现请求体是加密的,手动试了七八种常见AES密钥格式都解不开。后来翻到他App里内置的JS解密函数,顺手写了个Python脚本自动提取密钥+调用解密逻辑,三分钟跑出明文参数——这种场景,就是网络解密自动化脚本最实在的用武之地。
为什么手动解密越来越难
现在APP和网页普遍用动态密钥、时间戳混淆、多层嵌套加密(比如先RSA传AES密钥,再用AES-CBC加密数据),光靠Burp Suite或Fiddler点几下根本没法持续跟进。尤其遇到前端代码混淆+WebAssembly加密模块时,人眼逆向一天,不如脚本跑十秒。
一个真实可用的自动化解密脚本结构
核心思路很朴素:把浏览器里能跑通的解密逻辑,搬到本地Python里复现。关键不是重写算法,而是复用原有JS逻辑。
import execjs
import requests
# 读取网页中提取的混淆JS解密函数(已去minify)
with open("decrypt.js", "r", encoding="utf-8") as f:
js_code = f.read()
ctx = execjs.compile(js_code)
# 模拟抓包拿到的加密参数
enc_data = "U2FsdGVkX1+..."
timestamp = "1715823491"
# 直接调用原厂JS函数,返回明文
plain = ctx.call("decryptData", enc_data, timestamp)
print(plain) # {"uid":"10086","token":"xxx"}绕过WebAssembly加密的小技巧
有些新项目把核心解密逻辑编译进WASM,JS层只留调用接口。这时不用硬啃wasm反编译,直接在Chrome控制台打断点,找到wasm实例加载后的导出函数名,用Pyodide在Python里加载同个wasm文件即可:
from pyodide.http import pyfetch
import asyncio
async def call_wasm_decrypt(enc):
wasm_bin = await (await pyfetch("/static/core.wasm")).bytes()
# 加载并调用导出函数(函数名从devtools里抄)
result = await wasm_module.exports.decrypt(enc.encode())
return result.decode()别忘了加一层“防失效”机制
前端加密逻辑一更新,脚本就歇菜。建议在脚本开头加个自动检测环节:用requests请求目标页面,正则匹配最新JS文件URL,自动下载替换本地decrypt.js。再配合Git记录每次变更,哪天解密失败,一眼看出是密钥生成方式还是IV构造逻辑变了。
提醒一句
这类脚本只适合自己调试用的系统、已授权测试的测试环境,或者开源项目的通信分析。对未授权系统的加密流量做自动化解密,踩的是法律红线,不是技术能不能的问题。