1. 微信小程序API加解密机制解析
微信小程序采用HTTPS协议进行通信,所有API请求默认经过SSL加密传输。但开发者往往会在基础加密之上再增加业务层的加解密逻辑,主要出于以下考虑:
- 防止中间人攻击获取敏感数据
- 避免请求参数被篡改
- 保护核心业务逻辑不被逆向分析
常见的加解密方案包括:
- AES对称加密(最常用)
- RSA非对称加密(用于密钥交换)
- 自定义签名算法(参数防篡改)
- 数据压缩+Base64编码组合
重要提示:本文仅讨论技术原理,所有操作必须在小程序开发者授权范围内进行,违反用户协议的行为可能导致法律风险。
2. 抓包环境搭建与配置
2.1 Fiddler抓包工具配置
Fiddler Classic是目前最常用的HTTP调试代理工具,配置步骤如下:
- 安装最新版Fiddler Classic(v5.0+)
- 开启HTTPS解密功能:
- Tools > Options > HTTPS
- 勾选"Decrypt HTTPS traffic"
- 信任Fiddler根证书
- 设置手机代理:
- 确保手机和PC在同一局域网
- 手机WiFi设置手动代理,指向PC的IP和8888端口
- 过滤微信小程序流量:
# FiddlerScript规则 if (oSession.host.Contains("weixin.qq.com") || oSession.host.Contains("wx.qlogo.cn")) { return; }
2.2 常见抓包问题解决
| 问题现象 | 解决方案 |
|---|---|
| 证书错误 | 安装Fiddler根证书到手机信任存储 |
| 无网络 | 关闭手机代理后重试,检查防火墙设置 |
| 乱码数据 | 在Inspectors面板切换HexView查看原始数据 |
| 抓不到包 | 重启微信进程,清除小程序缓存 |
3. 加解密算法逆向分析
3.1 识别加密特征
通过抓包可观察到以下典型特征:
- 请求参数包含
encryptData等字段 - 响应数据为固定长度Base64字符串
- 请求头包含
x-signature等签名字段 - 相同操作每次请求参数完全不同
3.2 常见加密模式定位
AES加密识别:
- 数据长度为16/24/32字节的倍数
- 包含IV初始向量参数
- 常见模式:CBC/ECB/GCM
RSA加密识别:
- 数据长度固定(1024/2048位)
- 通常用于加密对称密钥
- 请求中包含
key=encryptedKey参数
自定义签名识别:
- 参数按特定顺序拼接
- 加入timestamp防重放
- 最后进行MD5/SHA256哈希
4. 实战解密流程
4.1 获取小程序源码
- 安卓手机获取小程序包:
adb pull /data/data/com.tencent.mm/MicroMsg/{userhash}/appbrand/pkg/ - 使用unwxapkg工具解包:
python unwxapkg.py __APP__.wxapkg
4.2 关键代码定位
在解包后的项目中搜索以下关键词:
// 加密相关 encryptData decryptData CryptoJS WXBizDataCrypt // 网络请求 wx.request wx.uploadFile4.3 解密算法还原示例
假设发现AES加密代码:
const CryptoJS = require('crypto-js') const key = 'b2c3d4e5f6g7h8i9' function encrypt(data) { return CryptoJS.AES.encrypt( JSON.stringify(data), CryptoJS.enc.Utf8.parse(key), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 } ).toString() }对应Python解密代码:
from Crypto.Cipher import AES import base64 def decrypt(encrypted_data): cipher = AES.new( key.encode('utf-8'), AES.MODE_ECB ) decrypted = cipher.decrypt( base64.b64decode(encrypted_data) ) return decrypted.decode('utf-8').strip()5. 高级对抗方案破解
5.1 证书固定(SSL Pinning)绕过
微信7.0+版本启用了证书固定,常规抓包会失败。解决方案:
使用Xposed模块:
- JustTrustMe
- TrustMeAlready
Frida脚本hook:
Java.perform(function() { var Certificate = Java.use('java.security.cert.Certificate'); var X509Certificate = Java.use('java.security.cert.X509Certificate'); // 绕过证书验证 Certificate.verify.overload('java.security.PublicKey').implementation = function() { console.log('Bypassing certificate verification'); return; }; });5.2 动态密钥防护
部分小程序会定期从服务端获取新密钥:
拦截密钥交换请求:
- 通常在登录后第一个API调用
- 路径包含
/getKey或/init
静态分析密钥生成逻辑:
// 常见密钥派生算法 const key = md5(deviceId + timestamp).substr(8,16)
6. 法律与道德边界
合法使用场景:
- 自家小程序的安全测试
- 授权范围内的渗透测试
- 学术研究(需脱敏处理)
绝对禁止行为:
- 破解他人小程序获取商业数据
- 绕过付费验证机制
- 篡改请求参数获取未授权服务
技术是把双刃剑,建议开发者将本文所述技术仅用于提升自身小程序的安全防护能力。