往下看还有一个x-api-eid-token
经过测试发现对其检测并不是很严格,重点还是这个h5st这个参数,废话不多说直接来分析吧
通过全局搜索关键词h5st,找到我们想要的接口位置打上断点进行页面刷新
这里我们找他的加密方法,发现他是由这个r方法进行加密这个h5st这个参数的
e是之前的对象做了处理,body已经知道是sha256后结果,中间一串固定,最后是一个当前时间戳。 r就是之前__genKey的结果。
接下来就是模拟生成算法了,这里我采用了纯算法,完全没必要扣js,毕竟一扣就是好几万行代码
CryptoJS = require('crypto-js');
const md5 = require('md5');
const _appId = "f961a",
fingerprint = "ni6mz59tt9ggt5w9",
_token = "tk03we9c31df518nK9QBfNOfZxyuMi7pYcPhmsaaoxSrIna8NGmEzCxxo71IQLNPqJsnfAWozsvQDZRFgVmlZzGiElFb",
_version = "4.1",
env = {
"sua": "Windows NT 10.0; Win64; x64",
"pp": {
"p2": "jd_51517ab15e972"
"extend": {
"pm": 0,
"wd": 0,
"l": 0,
"ls": 5,
"wk": 0
"random": "j52LDo5u-C",
"referer": "",
"v": "v1.6.1",
"fp": fingerprint
function sha256(text) {
return CryptoJS.SHA256(text).toString()
function collect() {
let iv = CryptoJS.enc.Utf8.parse('0102030405060708'),
key = CryptoJS.enc.Utf8.parse('HL4|FW#Chc3#q?0)'),
data = CryptoJS.enc.Utf8.parse(JSON.stringify(env, null, 2)); // data
aes = CryptoJS.AES.encrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
return aes.ciphertext.toString()//aes.toString()
function jd() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : Date.now()
, t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "yyyy-MM-dd"
, r = new Date(e)
, n = t
, i = {
"M+": r.getMonth() + 1,
"d+": r.getDate(),
"D+": r.getDate(),
"h+": r.getHours(),
"H+": r.getHours(),
"m+": r.getMinutes(),
"s+": r.getSeconds(),
"w+": r.getDay(),
"q+": Math.floor((r.getMonth() + 3) / 3),
"S+": r.getMilliseconds()
return /(y+)/i.test(n) && (n = n.replace(RegExp.$1, "".concat(r.getFullYear()).substr(4 - RegExp.$1.length))),
Object.keys(i).forEach(function (e) {
if (new RegExp("(".concat(e, ")")).test(n)) {
var t = "S+" === e ? "000" : "00";
n = n.replace(RegExp.$1, 1 == RegExp.$1.length ? i[e] : "".concat(t).concat(i[e]).substr("".concat(i[e]).length))
function h5st(t, r) {
let s = Date['now'](),
h = _appId,
p = fingerprint,
l = jd(s, 'yyyyMMddhhmmssSSS'),
ll = l + "04",
d = _token;
let o = CryptoJS.HmacMD5(`${d}${p}${ll}${h}b4v0JUR5Q4hw`, d).toString()
console.log(o)
// let o = sha256(`${d}${p}${ll}${h}b4v0JUR5Q4hw`)
let join_text = ""
t.forEach(function (element) {
join_text = join_text + "&" + element.key + ":" + element.value
// console.log(o + join_text.slice(1) + o)
let A = md5(o + join_text.slice(1) + o)
// let A = sha256('c142dab842b79943ebc623ee9b2bbe9459291a643c266631ec5f6656b155a1f1appid:jd-cphdeveloper-m&body:a4a9ad34ea9abb3c82748285b3c50adbdd1d33d429bbc815fc6a06afcc84cd2e&functionId:searchKeywordc142dab842b79943ebc623ee9b2bbe9459291a643c266631ec5f6656b155a1f1')
let x = [""['concat'](l), ""['concat'](fingerprint), ""['concat'](_appId), ""['concat'](_token), "".concat(A), ""['concat'](_version), ""['concat'](s), ""['concat'](r)].join(";");
console.log(`x ---> ${x}`)
return x
// 'appid:jd-cphdeveloper-m&body:0e9c74a186d8a8d37f812f418aa221fe72c5a926c3d3b2093338276cf96ec345&functionId:m_search_promise_realtime'
t = [
"key": "appid",
"value": "JDC_mall_cart"
"key": "body",
"value": body
"key": "client",
"value": "pc"
"key": "clientVersion",
"value": "1.0.0"
"key": "functionId",
"value": "pcCart_jc_getCurrentCart"
"key": "t",
"value": 1699339993250
r = collect()
h5st分别传两参数就是刚才分析的(e, r)
str = JSON.stringify({
"serInfo": {
"area": "12_988_993_58088",
"user-key": "6700b7d1-c4b6-42e3-aae9-0e79a85d471b"
"cartExt": {
"specialId": 1
body = s
ha256(str)
分享逆向经验 该文章主要讲解某东最新版h5s纯算 Vmp化纯算还原协议算法 逆向破解思路 算法剖析 手把手讲解,由浅入深 需要进一步学习可以 私 聊 辅导 定制爬虫软件,跟着Cute老师一步一步学会爬虫!!!本视频中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!!!多多支持,大佬们 一键三连多多投币!!!
分享逆向经验 当然Cute老师 该文章主要讲解某东最新版h5s4.7.2版本 纯算 Vmp化纯算还原协议算法 逆向破解思路 算法剖析 手把手讲解,由浅入深 需要进一步学习可以 私 聊 辅导 定制爬虫软件,跟着Cute老师一步一步学会爬虫 辅导爬虫数据采集 协议分析!!!本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!!!
这里这段代码就可以运行了,这里还不清楚加密方法是否在这段代码中声明的,所以我们打印一下。这里跳到了另一个 JS 文件中,观察这个文件的代码结构,可以发现它是一个自执行函数。并没有被定义,那么说明这个方法是在其它地方进行定义的,直接搜索。,可以在主页返回的源码找到一段自执行代码。,啥都不管,这里直接将代码全部复制下来运行。到这里加密方法就解决了,我们模拟加密一下。能够正常的输出结果,那么逆向流程就结束了。,这是一个异步方法,我们进到方法里面。加密,没有魔改,无需多言。因为加密方法是异步的,使用。
最近在2023年10.10 JD偷偷在M端更新了H5st4.2算法,今天我就在这里以m端搜索接口为例子分析一下给大家学习把代码组合测试一下,成功获取数据,收工技术交流 5LyB6bmFNTM0NjE1Njk=(base64解码)
最近无聊研究某东网页发现多了个h5st加密参数,在这里分析一下逆向步骤,跟大家共同学习。h5st加密,其实比较关键的也就第2段和第8段,其他基本都是明文,不难解决,最后尝试了一下算法用易语言还原出来,结果完全可以用难度不大技术交流QQ:53461569。
京东的token加密在 unify.min.js中
从图中可以看出 token是由 lr.hex_md5(r.report_ts + lr.md5Key)组成,通过测试可以发现,就是普通的md5加密
r.report_ts + lr.md5Key 参数获取
r.report_ts 看着ts两个词就感觉有点熟悉,通过查询发现就是13位时间戳
通过搜索 getCurTime() 方法,发现 report_ts 就是13为时间戳
md5Key 参数
通过全文搜索 md5