京东联盟h5st(3.1)逆向分析

声明:本文仅作学习交流,请遵守法律法规,不要恶意爬取网站。

网址:'aHR0cHM6Ly91bmlvbi5qZC5jb20vcHJvTWFuYWdlci9pbmRleA=='

h5st是京东系的反爬方式,即在接口中加上一个叫h5st的参数,h5st加密有不同的版本。本文提到的网站不是京东网站,是和京东有关联的一个网站,也有h5st参数,是3.1版本。

分析接口

要分析的是一个‘全部商品’接口,找到接口后先分析必要的参数。逐个分析可以发现必要的参数有headers中的origin和user-agent;cookies中的thor,以及params

很容易发现 headers和params中的functionId、appid、loginType是固定值,_是时间戳

需要参数来源的是cookies中的thor;params中的uuid、x-api-eid-token、h5st以及body中的searchUUID

再进一步分析会发现thor、uuid和x-api-eid-token都来源于cookies,分别对应thor、__jdu和3AB9D23F7A4B3CSS

没必要较劲他的什么时候产生的,哪个接口返回的,直接写死得了

所以我们重点要逆向的是h5st和searchUUID

逆向参数

h5st在源代码中位置倒是挺少,点进去打上断点跟代码,你会发现,等到了断点处,h5st的值已经产生了

怎么定位到具体的代码位置是在是个难点,唯有大胆猜测小心求证,逐步调试,观察作用域中参数值的变化

这里直接上结果:

searchUUID是一个随机字符串,每次切换页面时会变化,很好抠,也可以固定;

body先经过加密得到一个64位字符串,然后和其他的字符串拼接组成了h5st

body加密的位置:

body: K()(k()(i)).toString()

h5st加密的位置:

var D = this["__genSignP" + d(0, 1516, 1351)](z, c, a, r);

 至此我们可以再去看一下h5st的组成:

h5st: 20240226121601029;1733260139752348;586ae;tk03w04801dbb18nDfQXSjnTtkviyKrnh_npbbTrMXmrKSOfOfS6hSPJmKG_uyEocdAqBwHSNZYf4R8HHwT9MJBgpgyG;ac2846635dfb61c405b4ee623bccd274eb35866e3a3e9195013f2eeeb72f2db6;3.1;1708920961029;24c9ee85e67cf80746dd82817ecbeafc7a829b35c7f446a4c7d476cc9faa1d8834a93323ad7bce9bef1bba682b93d2e355076cc27b11bb228be53f32ed20565266eae147141141e0d154463e1733333213609f805a4de2ddf29a06541f6bb9892b80989b96d4724a0aaba834467cab40debef3f59396c2874c1a5d3ee361ffc6

//  yyyyMMddhhmmssSSS格式的日期字符串
20240226121601029;
//  浏览器指纹  跟浏览器有关 可以是固定值
1733260139752348;
//  appID 固定值
586ae;
//  token 应该是某个接口的返回值  可以是固定值
tk03w04801dbb18nDfQXSjnTtkviyKrnh_npbbTrMXmrKSOfOfS6hSPJmKG_uyEocdAqBwHSNZYf4R8HHwT9MJBgpgyG;
//  加密字符串  跟body有关  需破解
ac2846635dfb61c405b4ee623bccd274eb35866e3a3e9195013f2eeeb72f2db6;
//  h5st版本号  固定值
3.1;
//  时间戳
1708920961029;
//  跟环境相关 可以是固定值
24c9ee85e67cf80746dd82817ecbeafc7a829b35c7f446a4c7d476cc9faa1d8834a93323ad7bce9bef1bba682b93d2e355076cc27b11bb228be53f32ed20565266eae147141141e0d154463e1733333213609f805a4de2ddf29a06541f6bb9892b80989b96d4724a0aaba834467cab40debef3f59396c2874c1a5d3ee361ffc6

所以接下来就重点抠出h5st中第5段字符串的加密即可

成果展示

const CryptoJS = require('crypto-js');
var wp;
window = global;

var _ts = Date.now(),
    _fp = '1733260139752348',
    _appId = '586ae',
    _token = "tk03wb3c91c5518nXSL2egI9QuTKOLXLWBjx5lwKOpslUAXudyJSt0AmNRFyy4si5VCp4NpZB8wclFWOpK07zoso0J6C",
    _version = '3.1',
    _unknown = '24c9ee85e67cf80746dd82817ecbeafc7a829b35c7f446a4c7d476cc9faa1d8834a93323ad7bce9bef1bba682b93d2e355076cc27b11bb228be53f32ed20565266eae147141141e0d154463e1733333213609f805a4de2ddf29a06541f6bb9892b80989b96d4724a0aaba834467cab40debef3f59396c2874c1a5d3ee361ffc6'

var _td = ts2format(_ts)

!function (o) {
    "use strict";
    var e, n, t, a = {};

    function r(e) {
        var n = a[e];
        if (void 0 !== n)
            return n.exports;
        var t = a[e] = {
            id: e,
            loaded: !1,
            exports: {}
        };
        // console.log(e)
        return o[e].call(t.exports, t, t.exports, r),
            t.loaded = !0,
            t.exports
    }

    r.m = o,
        e = [],
        r.O = function (n, t, o, a) {
            if (!t) {
                var c = 1 / 0;
                for (u = 0; u < e.length; u++) {
                    t = e[u][0],
                        o = e[u][1],
                        a = e[u][2];
                    for (var i = !0, f = 0; f < t.length; f++)
                        (!1 & a || c >= a) && Object.keys(r.O).every((function (e) {
                                return r.O[e](t[f])
                            }
                        )) ? t.splice(f--, 1) : (i = !1,
                        a < c && (c = a));
                    if (i) {
                        e.splice(u--, 1);
                        var d = o();
                        void 0 !== d && (n = d)
                    }
                }
                return n
            }
            a = a || 0;
            for (var u = e.length; u > 0 && e[u - 1][2] > a; u--)
                e[u] = e[u - 1];
            e[u] = [t, o, a]
        }
        ,
        r.n = function (e) {
            var n = e && e.__esModule ? function () {
                    return e.default
                }
                : function () {
                    return e
                }
            ;
            return r.d(n, {
                a: n
            }),
                n
        }
        ,
        r.d = function (e, n) {
            for (var t in n)
                r.o(n, t) && !r.o(e, t) && Object.defineProperty(e, t, {
                    enumerable: !0,
                    get: n[t]
                })
        }
        ,
        r.f = {},
        r.e = function (e) {
            return Promise.all(Object.keys(r.f).reduce((function (n, t) {
                    return r.f[t](e, n),
                        n
                }
            ), []))
        }
        ,
        r.u = function (e) {
            return {
                34: "biservicefee",
                81: "promotion",
                378: "user",
                410: "marketActivities",
                621: "entire",
                685: "lineReport",
                869: "createShop",
                917: "agreement",
                929: "common-731babaf",
                973: "common-43dd7041",
                1131: "appMng",
                1276: "shopActPromotion",
                1288: "myApi",
                1621: "investmentEffect",
                1666: "planDetails",
                1806: "officalPromotion",
                1884: "taskDetail",
                1913: "jdauthentication",
                1970: "newWithdraw",
                1992: "cashDetail",
                2337: "withdraw",
                2412: "socialMediaMng",
                2479: "marketingCalendar",
                2481: "realTimeScreen",
                2527: "withdrawRecord",
                2690: "couponList",
                2795: "cashGiftCreate",
                2832: "taskSquare",
                2951: "RewardActivity",
                2970: "articlePromotion",
                2992: "myTask",
                3012: "subCommission",
                3386: "cashGiftDeposit",
                3513: "trafficMediaMng",
                3583: "webExtension",
                3712: "openplatform-9a53bcac",
                3756: "shopPromotion",
                3761: "openplatform-9a6b8f1e",
                3765: "skuAnalyse",
                3779: "active",
                3888: "external",
                3940: "cashCoupon",
                4163: "InterfaceManagement",
                4256: "channel",
                4565: "common-d91a9049",
                4738: "cpcMedia",
                4843: "openplatform-d91a9049",
                4962: "common-8912b8e4",
                5001: "groupList",
                5075: "planList",
                5142: "reverseInvestment",
                5177: "home",
                5313: "myStarEnlist2",
                5413: "recommendMng",
                5512: "accounting",
                5549: "jingPlanMng",
                5724: "common-69b0bd4f",
                5769: "appMedia",
                5847: "socialMediaExtension",
                5863: "projectDetail",
                6026: "InvestmentData",
                6103: "common-b4fa4e1a",
                6419: "batchMng",
                6596: "404",
                6653: "DataPromotion",
                6659: "common-4720890c",
                6682: "appExtension",
                6810: "common-c7713fe4",
                7012: "shopPromotionDetail",
                7066: "secretOrder",
                7253: "shopAnalyse",
                7468: "openOrder",
                7815: "chatExtension",
                7899: "custompromotion",
                7991: "webMng",
                8022: "cashGiftDepositResult",
                8273: "actAnalyse",
                8277: "cashGift",
                8300: "msg",
                8429: "helpcenter",
                8442: "moreProductList",
                8608: "channelPromotion",
                8722: "common-fb051ecb",
                8924: "initRevGroup",
                8983: "report",
                8989: "common-a07e9f05",
                9206: "trafficMediaExtension",
                9223: "initiate",
                9557: "couponPromotion",
                9621: "myInvoice",
                9664: "taskEffectData",
                9704: "batchDetail",
                9734: "myShop",
                9830: "darenBank",
                9847: "userTask",
                9851: "common-c0d952d5",
                9920: "operate",
                9940: "promotionSite",
                9974: "myStarEnlist"
            }[e] + "." + {
                34: "884dabbf",
                81: "516fbf65",
                378: "4fa7f455",
                410: "f3b3ce65",
                621: "779cbc2d",
                685: "635b41c3",
                869: "6e91e04e",
                917: "8931b075",
                929: "3c7249c4",
                973: "dd604fd9",
                1131: "5c758086",
                1276: "4afef4b0",
                1288: "efd9ca56",
                1621: "dd68ef97",
                1666: "15ddc024",
                1806: "2ce9aabc",
                1884: "26a69c37",
                1913: "7cf33bc8",
                1970: "2f4e7bbb",
                1992: "ede710f5",
                2337: "ed174f32",
                2412: "35ff0de8",
                2479: "a21c8c42",
                2481: "6fed6857",
                2527: "6a37ef3c",
                2690: "64ddf7cc",
                2795: "a674eb69",
                2832: "feecd3be",
                2951: "93b3e34d",
                2970: "0384070e",
                2992: "be5042ce",
                3012: "2347219c",
                3386: "1a1f7d84",
                3513: "c04a31fc",
                3583: "f5d3ef48",
                3712: "e2f73577",
                3756: "7a6444be",
                3761: "53e3439b",
                3765: "a4ec0efd",
                3779: "38223816",
                3888: "fce9007a",
                3940: "6e0a2517",
                4163: "f5764a34",
                4256: "d71746f3",
                4565: "38532a63",
                4738: "d5a92ea5",
                4843: "ac578919",
                4962: "46dd7b93",
                5001: "6ffabe1f",
                5075: "bf8fe0b0",
                5142: "f02f701e",
                5177: "95d0d33a",
                5313: "81217ce7",
                5413: "c7fd2e9a",
                5512: "9f7c1dc7",
                5549: "b90e6eb0",
                5724: "fae8a443",
                5769: "3026d89e",
                5847: "88f445a5",
                5863: "26a850a1",
                6026: "d554b6c8",
                6103: "9a594517",
                6419: "8a5d5b4f",
                6596: "43477835",
                6653: "e904d280",
                6659: "c79c71eb",
                6682: "9a980d14",
                6810: "767f177d",
                7012: "310763bf",
                7066: "0930edea",
                7253: "093b1d51",
                7468: "abc74f1b",
                7815: "7176c4b5",
                7899: "e3745e3e",
                7991: "bf2e88d9",
                8022: "0b3b8d2b",
                8273: "7597ef4f",
                8277: "4abc271d",
                8300: "386bd6f1",
                8429: "0a43b716",
                8442: "866be077",
                8608: "ce7516bf",
                8722: "d3db8be6",
                8924: "e678bf90",
                8983: "0eb1ef70",
                8989: "ba78e6ab",
                9206: "178b940f",
                9223: "bfda0e2b",
                9557: "a25c4ce7",
                9621: "56164042",
                9664: "fa4795b0",
                9704: "5721dc0a",
                9734: "74dcc744",
                9830: "de870bad",
                9847: "2b8f9834",
                9851: "cf04e91b",
                9920: "f2cde753",
                9940: "eb35820c",
                9974: "a83b6246"
            }[e] + ".js"
        }
        ,
        r.g = function () {
            if ("object" == typeof globalThis)
                return globalThis;
            try {
                return this || new Function("return this")()
            } catch (e) {
                if ("object" == typeof window)
                    return window
            }
        }(),
        r.o = function (e, n) {
            return Object.prototype.hasOwnProperty.call(e, n)
        }
        ,
        n = {},
        t = "JDUnion:",
        r.l = function (e, o, a, c) {
            if (n[e])
                n[e].push(o);
            else {
                var i, f;
                if (void 0 !== a)
                    for (var d = document.getElementsByTagName("script"), u = 0; u < d.length; u++) {
                        var b = d[u];
                        if (b.getAttribute("src") == e || b.getAttribute("data-webpack") == t + a) {
                            i = b;
                            break
                        }
                    }
                i || (f = !0,
                    (i = document.createElement("script")).charset = "utf-8",
                    i.timeout = 120,
                r.nc && i.setAttribute("nonce", r.nc),
                    i.setAttribute("data-webpack", t + a),
                    i.src = e),
                    n[e] = [o];
                var s = function (t, o) {
                    i.onerror = i.onload = null,
                        clearTimeout(l);
                    var a = n[e];
                    if (delete n[e],
                    i.parentNode && i.parentNode.removeChild(i),
                    a && a.forEach((function (e) {
                            return e(o)
                        }
                    )),
                        t)
                        return t(o)
                }
                    , l = setTimeout(s.bind(null, void 0, {
                    type: "timeout",
                    target: i
                }), 12e4);
                i.onerror = s.bind(null, i.onerror),
                    i.onload = s.bind(null, i.onload),
                f && document.head.appendChild(i)
            }
        }
        ,
        r.r = function (e) {
            "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
                value: "Module"
            }),
                Object.defineProperty(e, "__esModule", {
                    value: !0
                })
        }
        ,
        r.nmd = function (e) {
            return e.paths = [],
            e.children || (e.children = []),
                e
        }
        ,
        r.p = "//storage.360buyimg.com/pubfree-bucket/unionpc/b7e5298d5/",
        function () {
            var e = {
                6700: 0
            };
            r.f.j = function (n, t) {
                var o = r.o(e, n) ? e[n] : void 0;
                if (0 !== o)
                    if (o)
                        t.push(o[2]);
                    else if (6700 != n) {
                        var a = new Promise((function (t, a) {
                                o = e[n] = [t, a]
                            }
                        ));
                        t.push(o[2] = a);
                        var c = r.p + r.u(n)
                            , i = new Error;
                        r.l(c, (function (t) {
                                if (r.o(e, n) && (0 !== (o = e[n]) && (e[n] = void 0),
                                    o)) {
                                    var a = t && ("load" === t.type ? "missing" : t.type)
                                        , c = t && t.target && t.target.src;
                                    i.message = "Loading chunk " + n + " failed.\n(" + a + ": " + c + ")",
                                        i.name = "ChunkLoadError",
                                        i.type = a,
                                        i.request = c,
                                        o[1](i)
                                }
                            }
                        ), "chunk-" + n, n)
                    } else
                        e[n] = 0
            }
                ,
                r.O.j = function (n) {
                    return 0 === e[n]
                }
            ;
            var n = function (n, t) {
                var o, a, c = t[0], i = t[1], f = t[2], d = 0;
                if (c.some((function (n) {
                        return 0 !== e[n]
                    }
                ))) {
                    for (o in i)
                        r.o(i, o) && (r.m[o] = i[o]);
                    if (f)
                        var u = f(r)
                }
                for (n && n(t); d < c.length; d++)
                    a = c[d],
                    r.o(e, a) && e[a] && e[a][0](),
                        e[a] = 0;
                return r.O(u)
            }
                , t = window.webpackChunkJDUnion = window.webpackChunkJDUnion || [];
            t.forEach(n.bind(null, 0)),
                t.push = n.bind(null, t.push.bind(t))
        }(),
        r.nc = void 0
    wp = r
}({
    78249: function (t, n, e) {
        var i;
        t.exports = (i = i || function (t, n) {
            var i;
            if ("undefined" != typeof window && window.crypto && (i = window.crypto),
            "undefined" != typeof self && self.crypto && (i = self.crypto),
            "undefined" != typeof globalThis && globalThis.crypto && (i = globalThis.crypto),
            !i && "undefined" != typeof window && window.msCrypto && (i = window.msCrypto),
            !i && void 0 !== e.g && e.g.crypto && (i = e.g.crypto),
                !i)
                try {
                    i = e(42480)
                } catch (t) {
                }
            var r = function () {
                if (i) {
                    if ("function" == typeof i.getRandomValues)
                        try {
                            return i.getRandomValues(new Uint32Array(1))[0]
                        } catch (t) {
                        }
                    if ("function" == typeof i.randomBytes)
                        try {
                            return i.randomBytes(4).readInt32LE()
                        } catch (t) {
                        }
                }
                throw new Error("Native crypto module could not be used to get secure random number.")
            }
                , s = Object.create || function () {
                function t() {
                }

                return function (n) {
                    var e;
                    return t.prototype = n,
                        e = new t,
                        t.prototype = null,
                        e
                }
            }()
                , o = {}
                , u = o.lib = {}
                , f = u.Base = {
                extend: function (t) {
                    var n = s(this);
                    return t && n.mixIn(t),
                    n.hasOwnProperty("init") && this.init !== n.init || (n.init = function () {
                            n.$super.init.apply(this, arguments)
                        }
                    ),
                        n.init.prototype = n,
                        n.$super = this,
                        n
                },
                create: function () {
                    var t = this.extend();
                    return t.init.apply(t, arguments),
                        t
                },
                init: function () {
                },
                mixIn: function (t) {
                    for (var n in t)
                        t.hasOwnProperty(n) && (this[n] = t[n]);
                    t.hasOwnProperty("toString") && (this.toString = t.toString)
                },
                clone: function () {
                    return this.init.prototype.extend(this)
                }
            }
                , h = u.WordArray = f.extend({
                init: function (t, n) {
                    t = this.words = t || [],
                        this.sigBytes = null != n ? n : 4 * t.length
                },
                toString: function (t) {
                    return (t || l).stringify(this)
                },
                concat: function (t) {
                    var n = this.words
                        , e = t.words
                        , i = this.sigBytes
                        , r = t.sigBytes;
                    if (this.clamp(),
                    i % 4)
                        for (var s = 0; s < r; s++) {
                            var o = e[s >>> 2] >>> 24 - s % 4 * 8 & 255;
                            n[i + s >>> 2] |= o << 24 - (i + s) % 4 * 8
                        }
                    else
                        for (var u = 0; u < r; u += 4)
                            n[i + u >>> 2] = e[u >>> 2];
                    return this.sigBytes += r,
                        this
                },
                clamp: function () {
                    var n = this.words
                        , e = this.sigBytes;
                    n[e >>> 2] &= 4294967295 << 32 - e % 4 * 8,
                        n.length = t.ceil(e / 4)
                },
                clone: function () {
                    var t = f.clone.call(this);
                    return t.words = this.words.slice(0),
                        t
                },
                random: function (t) {
                    for (var n = [], e = 0; e < t; e += 4)
                        n.push(r());
                    return new h.init(n, t)
                }
            })
                , c = o.enc = {}
                , l = c.Hex = {
                stringify: function (t) {
                    for (var n = t.words, e = t.sigBytes, i = [], r = 0; r < e; r++) {
                        var s = n[r >>> 2] >>> 24 - r % 4 * 8 & 255;
                        i.push((s >>> 4).toString(16)),
                            i.push((15 & s).toString(16))
                    }
                    return i.join("")
                },
                parse: function (t) {
                    for (var n = t.length, e = [], i = 0; i < n; i += 2)
                        e[i >>> 3] |= parseInt(t.substr(i, 2), 16) << 24 - i % 8 * 4;
                    return new h.init(e, n / 2)
                }
            }
                , a = c.Latin1 = {
                stringify: function (t) {
                    for (var n = t.words, e = t.sigBytes, i = [], r = 0; r < e; r++) {
                        var s = n[r >>> 2] >>> 24 - r % 4 * 8 & 255;
                        i.push(String.fromCharCode(s))
                    }
                    return i.join("")
                },
                parse: function (t) {
                    for (var n = t.length, e = [], i = 0; i < n; i++)
                        e[i >>> 2] |= (255 & t.charCodeAt(i)) << 24 - i % 4 * 8;
                    return new h.init(e, n)
                }
            }
                , d = c.Utf8 = {
                stringify: function (t) {
                    try {
                        return decodeURIComponent(escape(a.stringify(t)))
                    } catch (t) {
                        throw new Error("Malformed UTF-8 data")
                    }
                },
                parse: function (t) {
                    return a.parse(unescape(encodeURIComponent(t)))
                }
            }
                , p = u.BufferedBlockAlgorithm = f.extend({
                reset: function () {
                    this._data = new h.init,
                        this._nDataBytes = 0
                },
                _append: function (t) {
                    "string" == typeof t && (t = d.parse(t)),
                        this._data.concat(t),
                        this._nDataBytes += t.sigBytes
                },
                _process: function (n) {
                    var e, i = this._data, r = i.words, s = i.sigBytes, o = this.blockSize, u = s / (4 * o),
                        f = (u = n ? t.ceil(u) : t.max((0 | u) - this._minBufferSize, 0)) * o, c = t.min(4 * f, s);
                    if (f) {
                        for (var l = 0; l < f; l += o)
                            this._doProcessBlock(r, l);
                        e = r.splice(0, f),
                            i.sigBytes -= c
                    }
                    return new h.init(e, c)
                },
                clone: function () {
                    var t = f.clone.call(this);
                    return t._data = this._data.clone(),
                        t
                },
                _minBufferSize: 0
            })
                , g = (u.Hasher = p.extend({
                cfg: f.extend(),
                init: function (t) {
                    this.cfg = this.cfg.extend(t),
                        this.reset()
                },
                reset: function () {
                    p.reset.call(this),
                        this._doReset()
                },
                update: function (t) {
                    return this._append(t),
                        this._process(),
                        this
                },
                finalize: function (t) {
                    return t && this._append(t),
                        this._doFinalize()
                },
                blockSize: 16,
                _createHelper: function (t) {
                    return function (n, e) {
                        return new t.init(e).finalize(n)
                    }
                },
                _createHmacHelper: function (t) {
                    return function (n, e) {
                        return new g.HMAC.init(t, e).finalize(n)
                    }
                }
            }),
                o.algo = {});
            return o
        }(Math),
            i)
    },
    52153: function (t, n, e) {
        var i;
        t.exports = (i = e(78249),
            function (t) {
                var n = i
                    , e = n.lib
                    , r = e.WordArray
                    , s = e.Hasher
                    , o = n.algo
                    , u = []
                    , f = [];
                !function () {
                    function n(n) {
                        for (var e = t.sqrt(n), i = 2; i <= e; i++)
                            if (!(n % i))
                                return !1;
                        return !0
                    }

                    function e(t) {
                        return 4294967296 * (t - (0 | t)) | 0
                    }

                    for (var i = 2, r = 0; r < 64;)
                        n(i) && (r < 8 && (u[r] = e(t.pow(i, .5))),
                            f[r] = e(t.pow(i, 1 / 3)),
                            r++),
                            i++
                }();
                var h = []
                    , c = o.SHA256 = s.extend({
                    _doReset: function () {
                        this._hash = new r.init(u.slice(0))
                    },
                    _doProcessBlock: function (t, n) {
                        for (var e = this._hash.words, i = e[0], r = e[1], s = e[2], o = e[3], u = e[4], c = e[5], l = e[6], a = e[7], d = 0; d < 64; d++) {
                            if (d < 16)
                                h[d] = 0 | t[n + d];
                            else {
                                var p = h[d - 15]
                                    , g = (p << 25 | p >>> 7) ^ (p << 14 | p >>> 18) ^ p >>> 3
                                    , m = h[d - 2]
                                    , y = (m << 15 | m >>> 17) ^ (m << 13 | m >>> 19) ^ m >>> 10;
                                h[d] = g + h[d - 7] + y + h[d - 16]
                            }
                            var v = i & r ^ i & s ^ r & s
                                , w = (i << 30 | i >>> 2) ^ (i << 19 | i >>> 13) ^ (i << 10 | i >>> 22)
                                ,
                                $ = a + ((u << 26 | u >>> 6) ^ (u << 21 | u >>> 11) ^ (u << 7 | u >>> 25)) + (u & c ^ ~u & l) + f[d] + h[d];
                            a = l,
                                l = c,
                                c = u,
                                u = o + $ | 0,
                                o = s,
                                s = r,
                                r = i,
                                i = $ + (w + v) | 0
                        }
                        e[0] = e[0] + i | 0,
                            e[1] = e[1] + r | 0,
                            e[2] = e[2] + s | 0,
                            e[3] = e[3] + o | 0,
                            e[4] = e[4] + u | 0,
                            e[5] = e[5] + c | 0,
                            e[6] = e[6] + l | 0,
                            e[7] = e[7] + a | 0
                    },
                    _doFinalize: function () {
                        var n = this._data
                            , e = n.words
                            , i = 8 * this._nDataBytes
                            , r = 8 * n.sigBytes;
                        return e[r >>> 5] |= 128 << 24 - r % 32,
                            e[14 + (r + 64 >>> 9 << 4)] = t.floor(i / 4294967296),
                            e[15 + (r + 64 >>> 9 << 4)] = i,
                            n.sigBytes = 4 * e.length,
                            this._process(),
                            this._hash
                    },
                    clone: function () {
                        var t = s.clone.call(this);
                        return t._hash = this._hash.clone(),
                            t
                    }
                });
                n.SHA256 = s._createHelper(c),
                    n.HmacSHA256 = s._createHmacHelper(c)
            }(Math),
            i.SHA256)
    },
});

function ts2format(ts) {
    const date = new Date(ts);
    const y = date.getFullYear(),
        m = String(date.getMonth() + 1).padStart(2, '0'),
        d = String(date.getDate()).padStart(2, '0'),
        h = String(date.getHours()).padStart(2, '0'),
        mi = String(date.getMinutes()).padStart(2, '0'),
        s = String(date.getSeconds()).padStart(2, '0'),
        ms = String(date.getMilliseconds()).padStart(3, '0')
    return `${y}${m}${d}${h}${mi}${s}${ms}`;
}

function body(obj) {
    const F = wp(52153),
        K = wp.n(F),
        args_str = JSON.stringify(obj)
    return K()(args_str).toString()
}

function secret_str() {
    var rd = '4LP439v0MSSD';
    var str = "".concat(_token).concat(_fp).concat(_td).concat(_appId).concat(rd);
    return CryptoJS.SHA256(str).toString(CryptoJS.enc.Hex);
}

function encrypt_data(r, i) {
    function convertToQueryString(data) {
        return data.map(item => `${item.key}:${item.value}`).join('&');
    }

    const c = convertToQueryString(i)
    return CryptoJS.HmacSHA256(c, r).toString(CryptoJS.enc.Hex)
}

function h5st(p) {
    const b = body(p)
    const jsonArray = [
        {
            "key": "appid",
            "value": "unionpc"
        },
        {
            "key": "body",
            "value": b
        },
        {
            "key": "functionId",
            "value": "unionSearch"
        }
    ]
    const secret = secret_str()
    const _encrypt = encrypt_data(secret, jsonArray)

    const dt = "".concat(_td),
        fp = "".concat(_fp),
        appId = "".concat(_appId),
        tk = "".concat(_token),
        encrypt = "".concat(_encrypt),
        version = "".concat(_version),
        ts = "".concat(_ts),
        unknown = "".concat(_unknown)
    return [dt, fp, appId, tk, encrypt, version, ts, unknown].join(";")
}


e = {
    "funName": "search",
    "version": "v3",
    "source": 20310,
    "param": {
        "pageNo": 2,
        "pageSize": 60,
        "searchUUID": "e7fb274ce31247e689982c7375d29f5e",
        "bonusIds": null,
        "category1": null,
        "category2": null,
        "category3": null,
        "deliveryType": null,
        "wlRate": null,
        "maxWlRate": null,
        "fromPrice": null,
        "toPrice": null,
        "hasCoupon": null,
        "isHot": null,
        "isNeedPreSale": null,
        "isPinGou": null,
        "isZY": null,
        "isCare": null,
        "lock": null,
        "orientationFlag": null,
        "sort": null,
        "sortName": null,
        "keyWord": "",
        "searchType": "st3",
        "keywordType": "kt0"
    },
    "clientPageId": "jingfen_pc"
}
hs = h5st(e)
console.log("h5st:", hs);

import json
import requests
import execjs


thor = ''
_jdu = ''
_3AB9D23F7A4B3CSS = ''

url = "https://api.m.jd.com/api"
headers = {
    "Accept": "application/json, text/plain, */*",
    "origin": "https://union.jd.com",
    "Referer": "https://union.jd.com/",
    "X-Referer-Page": "https://union.jd.com/proManager/index",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
}
cookies = {"thor": thor}


class UnionJD:
    def __init__(self):
        self.js_code = execjs.compile(open('unionJD.js', 'r', encoding='utf-8').read())

    def get_params(self, page):
        params = {
            "functionId": "unionSearch",
            "appid": "unionpc",
            "loginType": "3",
            "uuid": _jdu,
            "x-api-eid-token": _3AB9D23F7A4B3CSS
        }
        body = {"funName": "search",
                "version": "v3",
                "source": 20310,
                "param": {"pageNo": page,
                          "pageSize": 60,
                          "searchUUID": "e47cfeb25c054a5886ca6f63449b0093",
                          "bonusIds": None,
                          "category1": None,
                          "category2": None,
                          "category3": None,
                          "deliveryType": None,
                          "wlRate": None,
                          "maxWlRate": None,
                          "fromPrice": None,
                          "toPrice": None,
                          "hasCoupon": None,
                          "isHot": None,
                          "isNeedPreSale": None,
                          "isPinGou": None,
                          "isZY": None,
                          "isCare": None,
                          "lock": None,
                          "orientationFlag": None,
                          "sort": None,
                          "sortName": None,
                          "keyWord": "",
                          "searchType": "st3",
                          "keywordType": "kt0"
                      },
                "clientPageId": "jingfen_pc"
            }
        h5st = self.js_code.call('h5st', body)
        ts = h5st.split(';')[6]
        params['_'] = ts
        params['h5st'] = h5st
        params['body'] = json.dumps(body)
        return params

    def request_data(self, page):
        params = self.get_params(page)
        response = requests.get(url, headers=headers, cookies=cookies, params=params)
        return response


if __name__ == '__main__':
    u = UnionJD()
    p = u.request_data(1)
    print(p.text)
    print(p.status_code)



本文重点是h5st的逆向,其他参数都使用的固定值,仅供参考;

 另外cookies值需要登陆后手动填写,接口能正常获取到相应,但有时会403,尤其是访问频率快时,可能是网站有些校验,有需要的可以再深入研究

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值