第一次接触某团商家后台的加密参数时,我和大多数逆向新手一样感到无从下手。mtgsig 1.1参数就像一扇紧闭的大门,而H5guard算法则是门口凶猛的看门狗。经过多次实战,我发现这套加密机制主要包含三个关键部分:版本标识(a1)、时间戳(a2)和动态生成的加密字符串(a3/a5/a6)。其中a3与用户会话相关,a5和a6则是核心加密结果。
在最新抓包数据中,mtgsig参数通常呈现这样的结构:
json复制{
"a1":"1.1",
"a2":1741916388817,
"a3":"z0u89y82y7xw599w021x55v507v835448057y35v7uw9795864z8z9zu",
"a5":"Th0orxZzYh0ZXe+pBUBrPj+76C/HwcrP",
"a6":"h1.5z8Lbkh4D/SJax6K/k+Zd9u+3R4tPZU3wbPUHiGt/LyvmIf/fUTjT3yqkuOjCpsY7HzaCmgkUvrWOaiSyB/Rpz166brpcXHldVTwITgaT47mFCZCtQerceGUDaFEU2Dp7dECDUFJjS3UFV0A81ULHxY2ZwrOvOasJZo+K+ht4ftU0B2MxsfeFQxKhH2jVswdorFMpx7yAXHT4qvGC19d5RXEcNMv/YD6Ar4j2dozKkjED2isCXXDSmnTFejxYJ1OHatJaeoyBUynvqQTJvnTW9APzB81UWQq7MUx36uaaCjoiuvMCJYMkJg96JwSheMRB38a36cOnLa7oE0LQksGOwApM+N420Xkyxw2a89mh4SNqXGKeNeTjJAWf5in4+HVC7L39K56s1gpHnsPl1H9PQA==",
"x0":4,
"d1":"44339d845fc1562ef39a80651bf2cbae"
}
某团的H5guard会像侦探一样检查浏览器环境,主要关注这些对象:
我在Node.js中补环境的配置如下:
javascript复制const jsdom = require("jsdom");
const {JSDOM} = jsdom;
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`, {
url: "https://h5.waimai.meituan.com/waimai/mindex/home",
runScripts: 'dangerously'
})
window = dom.window;
document = window.document;
navigator = window.navigator = {
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)'
};
// 必须精确配置的location对象
location = {
href: "https://h5.waimai.meituan.com/waimai/mindex/home",
origin: "https://h5.waimai.meituan.com",
hostname: "h5.waimai.meituan.com"
};
H5guard的JavaScript代码经过多重混淆:
我常用的破解方法是:
例如这段典型控制流:
javascript复制function _0x12ab(a,b) {
return (a << b) | (a >>> (32 - b));
}
// 实际是标准的左循环移位操作
a3参数实际上是多个环境变量的组合产物:
实测生成过程需要这些步骤:
javascript复制function generateA3() {
const cookieStr = document.cookie;
const deviceFingerprint = getDeviceFP();
return md5(cookieStr + deviceFingerprint).slice(0, 32);
}
这两个参数才是真正的难点,其生成涉及:
关键代码段示例:
javascript复制const crypto = require('crypto');
function encryptA5(plainText) {
const publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA${keyData}...
-----END PUBLIC KEY-----`;
return crypto.publicEncrypt(
{key: publicKey, padding: crypto.constants.RSA_PKCS1_PADDING},
Buffer.from(plainText)
).toString('base64');
}
在Node.js中完美模拟浏览器环境需要特别注意:
这是我总结的必备补丁:
javascript复制// 修复定时器问题
const originalSetInterval = setInterval;
setInterval = (fn, delay) => {
const timer = originalSetInterval(fn, delay);
process.on('exit', () => clearInterval(timer));
return timer;
};
// 补全缺失的浏览器API
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (cb) => setTimeout(cb, 16);
}
最终可运行的完整流程应该是:
核心调用示例:
javascript复制const H5guard = require('./H5guard.patched.js');
function getMtgsig(params) {
H5guard.init(); // 必须初始化
const result = H5guard.encrypt(JSON.stringify(params));
return {
a1: '1.1',
a2: Date.now(),
a3: generateA3(),
a5: result.cipherText,
a6: result.signature,
x0: 4,
d1: md5(params)
};
}
在逆向过程中最常遇到的坑是环境检测不完整,比如漏掉了window.outerWidth这样的属性检测。建议大家在开发时准备好浏览器环境快照工具,将真实环境的所有属性记录下来逐个比对补全。