往下看还有一个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