当前位置:   article > 正文

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

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的组成:

  1. h5st: 20240226121601029;1733260139752348;586ae;tk03w04801dbb18nDfQXSjnTtkviyKrnh_npbbTrMXmrKSOfOfS6hSPJmKG_uyEocdAqBwHSNZYf4R8HHwT9MJBgpgyG;ac2846635dfb61c405b4ee623bccd274eb35866e3a3e9195013f2eeeb72f2db6;3.1;1708920961029;24c9ee85e67cf80746dd82817ecbeafc7a829b35c7f446a4c7d476cc9faa1d8834a93323ad7bce9bef1bba682b93d2e355076cc27b11bb228be53f32ed20565266eae147141141e0d154463e1733333213609f805a4de2ddf29a06541f6bb9892b80989b96d4724a0aaba834467cab40debef3f59396c2874c1a5d3ee361ffc6
  2. // yyyyMMddhhmmssSSS格式的日期字符串
  3. 20240226121601029;
  4. // 浏览器指纹 跟浏览器有关 可以是固定值
  5. 1733260139752348;
  6. // appID 固定值
  7. 586ae;
  8. // token 应该是某个接口的返回值 可以是固定值
  9. tk03w04801dbb18nDfQXSjnTtkviyKrnh_npbbTrMXmrKSOfOfS6hSPJmKG_uyEocdAqBwHSNZYf4R8HHwT9MJBgpgyG;
  10. // 加密字符串 跟body有关 需破解
  11. ac2846635dfb61c405b4ee623bccd274eb35866e3a3e9195013f2eeeb72f2db6;
  12. // h5st版本号 固定值
  13. 3.1;
  14. // 时间戳
  15. 1708920961029;
  16. // 跟环境相关 可以是固定值
  17. 24c9ee85e67cf80746dd82817ecbeafc7a829b35c7f446a4c7d476cc9faa1d8834a93323ad7bce9bef1bba682b93d2e355076cc27b11bb228be53f32ed20565266eae147141141e0d154463e1733333213609f805a4de2ddf29a06541f6bb9892b80989b96d4724a0aaba834467cab40debef3f59396c2874c1a5d3ee361ffc6

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

成果展示

  1. const CryptoJS = require('crypto-js');
  2. var wp;
  3. window = global;
  4. var _ts = Date.now(),
  5. _fp = '1733260139752348',
  6. _appId = '586ae',
  7. _token = "tk03wb3c91c5518nXSL2egI9QuTKOLXLWBjx5lwKOpslUAXudyJSt0AmNRFyy4si5VCp4NpZB8wclFWOpK07zoso0J6C",
  8. _version = '3.1',
  9. _unknown = '24c9ee85e67cf80746dd82817ecbeafc7a829b35c7f446a4c7d476cc9faa1d8834a93323ad7bce9bef1bba682b93d2e355076cc27b11bb228be53f32ed20565266eae147141141e0d154463e1733333213609f805a4de2ddf29a06541f6bb9892b80989b96d4724a0aaba834467cab40debef3f59396c2874c1a5d3ee361ffc6'
  10. var _td = ts2format(_ts)
  11. !function (o) {
  12. "use strict";
  13. var e, n, t, a = {};
  14. function r(e) {
  15. var n = a[e];
  16. if (void 0 !== n)
  17. return n.exports;
  18. var t = a[e] = {
  19. id: e,
  20. loaded: !1,
  21. exports: {}
  22. };
  23. // console.log(e)
  24. return o[e].call(t.exports, t, t.exports, r),
  25. t.loaded = !0,
  26. t.exports
  27. }
  28. r.m = o,
  29. e = [],
  30. r.O = function (n, t, o, a) {
  31. if (!t) {
  32. var c = 1 / 0;
  33. for (u = 0; u < e.length; u++) {
  34. t = e[u][0],
  35. o = e[u][1],
  36. a = e[u][2];
  37. for (var i = !0, f = 0; f < t.length; f++)
  38. (!1 & a || c >= a) && Object.keys(r.O).every((function (e) {
  39. return r.O[e](t[f])
  40. }
  41. )) ? t.splice(f--, 1) : (i = !1,
  42. a < c && (c = a));
  43. if (i) {
  44. e.splice(u--, 1);
  45. var d = o();
  46. void 0 !== d && (n = d)
  47. }
  48. }
  49. return n
  50. }
  51. a = a || 0;
  52. for (var u = e.length; u > 0 && e[u - 1][2] > a; u--)
  53. e[u] = e[u - 1];
  54. e[u] = [t, o, a]
  55. }
  56. ,
  57. r.n = function (e) {
  58. var n = e && e.__esModule ? function () {
  59. return e.default
  60. }
  61. : function () {
  62. return e
  63. }
  64. ;
  65. return r.d(n, {
  66. a: n
  67. }),
  68. n
  69. }
  70. ,
  71. r.d = function (e, n) {
  72. for (var t in n)
  73. r.o(n, t) && !r.o(e, t) && Object.defineProperty(e, t, {
  74. enumerable: !0,
  75. get: n[t]
  76. })
  77. }
  78. ,
  79. r.f = {},
  80. r.e = function (e) {
  81. return Promise.all(Object.keys(r.f).reduce((function (n, t) {
  82. return r.f[t](e, n),
  83. n
  84. }
  85. ), []))
  86. }
  87. ,
  88. r.u = function (e) {
  89. return {
  90. 34: "biservicefee",
  91. 81: "promotion",
  92. 378: "user",
  93. 410: "marketActivities",
  94. 621: "entire",
  95. 685: "lineReport",
  96. 869: "createShop",
  97. 917: "agreement",
  98. 929: "common-731babaf",
  99. 973: "common-43dd7041",
  100. 1131: "appMng",
  101. 1276: "shopActPromotion",
  102. 1288: "myApi",
  103. 1621: "investmentEffect",
  104. 1666: "planDetails",
  105. 1806: "officalPromotion",
  106. 1884: "taskDetail",
  107. 1913: "jdauthentication",
  108. 1970: "newWithdraw",
  109. 1992: "cashDetail",
  110. 2337: "withdraw",
  111. 2412: "socialMediaMng",
  112. 2479: "marketingCalendar",
  113. 2481: "realTimeScreen",
  114. 2527: "withdrawRecord",
  115. 2690: "couponList",
  116. 2795: "cashGiftCreate",
  117. 2832: "taskSquare",
  118. 2951: "RewardActivity",
  119. 2970: "articlePromotion",
  120. 2992: "myTask",
  121. 3012: "subCommission",
  122. 3386: "cashGiftDeposit",
  123. 3513: "trafficMediaMng",
  124. 3583: "webExtension",
  125. 3712: "openplatform-9a53bcac",
  126. 3756: "shopPromotion",
  127. 3761: "openplatform-9a6b8f1e",
  128. 3765: "skuAnalyse",
  129. 3779: "active",
  130. 3888: "external",
  131. 3940: "cashCoupon",
  132. 4163: "InterfaceManagement",
  133. 4256: "channel",
  134. 4565: "common-d91a9049",
  135. 4738: "cpcMedia",
  136. 4843: "openplatform-d91a9049",
  137. 4962: "common-8912b8e4",
  138. 5001: "groupList",
  139. 5075: "planList",
  140. 5142: "reverseInvestment",
  141. 5177: "home",
  142. 5313: "myStarEnlist2",
  143. 5413: "recommendMng",
  144. 5512: "accounting",
  145. 5549: "jingPlanMng",
  146. 5724: "common-69b0bd4f",
  147. 5769: "appMedia",
  148. 5847: "socialMediaExtension",
  149. 5863: "projectDetail",
  150. 6026: "InvestmentData",
  151. 6103: "common-b4fa4e1a",
  152. 6419: "batchMng",
  153. 6596: "404",
  154. 6653: "DataPromotion",
  155. 6659: "common-4720890c",
  156. 6682: "appExtension",
  157. 6810: "common-c7713fe4",
  158. 7012: "shopPromotionDetail",
  159. 7066: "secretOrder",
  160. 7253: "shopAnalyse",
  161. 7468: "openOrder",
  162. 7815: "chatExtension",
  163. 7899: "custompromotion",
  164. 7991: "webMng",
  165. 8022: "cashGiftDepositResult",
  166. 8273: "actAnalyse",
  167. 8277: "cashGift",
  168. 8300: "msg",
  169. 8429: "helpcenter",
  170. 8442: "moreProductList",
  171. 8608: "channelPromotion",
  172. 8722: "common-fb051ecb",
  173. 8924: "initRevGroup",
  174. 8983: "report",
  175. 8989: "common-a07e9f05",
  176. 9206: "trafficMediaExtension",
  177. 9223: "initiate",
  178. 9557: "couponPromotion",
  179. 9621: "myInvoice",
  180. 9664: "taskEffectData",
  181. 9704: "batchDetail",
  182. 9734: "myShop",
  183. 9830: "darenBank",
  184. 9847: "userTask",
  185. 9851: "common-c0d952d5",
  186. 9920: "operate",
  187. 9940: "promotionSite",
  188. 9974: "myStarEnlist"
  189. }[e] + "." + {
  190. 34: "884dabbf",
  191. 81: "516fbf65",
  192. 378: "4fa7f455",
  193. 410: "f3b3ce65",
  194. 621: "779cbc2d",
  195. 685: "635b41c3",
  196. 869: "6e91e04e",
  197. 917: "8931b075",
  198. 929: "3c7249c4",
  199. 973: "dd604fd9",
  200. 1131: "5c758086",
  201. 1276: "4afef4b0",
  202. 1288: "efd9ca56",
  203. 1621: "dd68ef97",
  204. 1666: "15ddc024",
  205. 1806: "2ce9aabc",
  206. 1884: "26a69c37",
  207. 1913: "7cf33bc8",
  208. 1970: "2f4e7bbb",
  209. 1992: "ede710f5",
  210. 2337: "ed174f32",
  211. 2412: "35ff0de8",
  212. 2479: "a21c8c42",
  213. 2481: "6fed6857",
  214. 2527: "6a37ef3c",
  215. 2690: "64ddf7cc",
  216. 2795: "a674eb69",
  217. 2832: "feecd3be",
  218. 2951: "93b3e34d",
  219. 2970: "0384070e",
  220. 2992: "be5042ce",
  221. 3012: "2347219c",
  222. 3386: "1a1f7d84",
  223. 3513: "c04a31fc",
  224. 3583: "f5d3ef48",
  225. 3712: "e2f73577",
  226. 3756: "7a6444be",
  227. 3761: "53e3439b",
  228. 3765: "a4ec0efd",
  229. 3779: "38223816",
  230. 3888: "fce9007a",
  231. 3940: "6e0a2517",
  232. 4163: "f5764a34",
  233. 4256: "d71746f3",
  234. 4565: "38532a63",
  235. 4738: "d5a92ea5",
  236. 4843: "ac578919",
  237. 4962: "46dd7b93",
  238. 5001: "6ffabe1f",
  239. 5075: "bf8fe0b0",
  240. 5142: "f02f701e",
  241. 5177: "95d0d33a",
  242. 5313: "81217ce7",
  243. 5413: "c7fd2e9a",
  244. 5512: "9f7c1dc7",
  245. 5549: "b90e6eb0",
  246. 5724: "fae8a443",
  247. 5769: "3026d89e",
  248. 5847: "88f445a5",
  249. 5863: "26a850a1",
  250. 6026: "d554b6c8",
  251. 6103: "9a594517",
  252. 6419: "8a5d5b4f",
  253. 6596: "43477835",
  254. 6653: "e904d280",
  255. 6659: "c79c71eb",
  256. 6682: "9a980d14",
  257. 6810: "767f177d",
  258. 7012: "310763bf",
  259. 7066: "0930edea",
  260. 7253: "093b1d51",
  261. 7468: "abc74f1b",
  262. 7815: "7176c4b5",
  263. 7899: "e3745e3e",
  264. 7991: "bf2e88d9",
  265. 8022: "0b3b8d2b",
  266. 8273: "7597ef4f",
  267. 8277: "4abc271d",
  268. 8300: "386bd6f1",
  269. 8429: "0a43b716",
  270. 8442: "866be077",
  271. 8608: "ce7516bf",
  272. 8722: "d3db8be6",
  273. 8924: "e678bf90",
  274. 8983: "0eb1ef70",
  275. 8989: "ba78e6ab",
  276. 9206: "178b940f",
  277. 9223: "bfda0e2b",
  278. 9557: "a25c4ce7",
  279. 9621: "56164042",
  280. 9664: "fa4795b0",
  281. 9704: "5721dc0a",
  282. 9734: "74dcc744",
  283. 9830: "de870bad",
  284. 9847: "2b8f9834",
  285. 9851: "cf04e91b",
  286. 9920: "f2cde753",
  287. 9940: "eb35820c",
  288. 9974: "a83b6246"
  289. }[e] + ".js"
  290. }
  291. ,
  292. r.g = function () {
  293. if ("object" == typeof globalThis)
  294. return globalThis;
  295. try {
  296. return this || new Function("return this")()
  297. } catch (e) {
  298. if ("object" == typeof window)
  299. return window
  300. }
  301. }(),
  302. r.o = function (e, n) {
  303. return Object.prototype.hasOwnProperty.call(e, n)
  304. }
  305. ,
  306. n = {},
  307. t = "JDUnion:",
  308. r.l = function (e, o, a, c) {
  309. if (n[e])
  310. n[e].push(o);
  311. else {
  312. var i, f;
  313. if (void 0 !== a)
  314. for (var d = document.getElementsByTagName("script"), u = 0; u < d.length; u++) {
  315. var b = d[u];
  316. if (b.getAttribute("src") == e || b.getAttribute("data-webpack") == t + a) {
  317. i = b;
  318. break
  319. }
  320. }
  321. i || (f = !0,
  322. (i = document.createElement("script")).charset = "utf-8",
  323. i.timeout = 120,
  324. r.nc && i.setAttribute("nonce", r.nc),
  325. i.setAttribute("data-webpack", t + a),
  326. i.src = e),
  327. n[e] = [o];
  328. var s = function (t, o) {
  329. i.onerror = i.onload = null,
  330. clearTimeout(l);
  331. var a = n[e];
  332. if (delete n[e],
  333. i.parentNode && i.parentNode.removeChild(i),
  334. a && a.forEach((function (e) {
  335. return e(o)
  336. }
  337. )),
  338. t)
  339. return t(o)
  340. }
  341. , l = setTimeout(s.bind(null, void 0, {
  342. type: "timeout",
  343. target: i
  344. }), 12e4);
  345. i.onerror = s.bind(null, i.onerror),
  346. i.onload = s.bind(null, i.onload),
  347. f && document.head.appendChild(i)
  348. }
  349. }
  350. ,
  351. r.r = function (e) {
  352. "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
  353. value: "Module"
  354. }),
  355. Object.defineProperty(e, "__esModule", {
  356. value: !0
  357. })
  358. }
  359. ,
  360. r.nmd = function (e) {
  361. return e.paths = [],
  362. e.children || (e.children = []),
  363. e
  364. }
  365. ,
  366. r.p = "//storage.360buyimg.com/pubfree-bucket/unionpc/b7e5298d5/",
  367. function () {
  368. var e = {
  369. 6700: 0
  370. };
  371. r.f.j = function (n, t) {
  372. var o = r.o(e, n) ? e[n] : void 0;
  373. if (0 !== o)
  374. if (o)
  375. t.push(o[2]);
  376. else if (6700 != n) {
  377. var a = new Promise((function (t, a) {
  378. o = e[n] = [t, a]
  379. }
  380. ));
  381. t.push(o[2] = a);
  382. var c = r.p + r.u(n)
  383. , i = new Error;
  384. r.l(c, (function (t) {
  385. if (r.o(e, n) && (0 !== (o = e[n]) && (e[n] = void 0),
  386. o)) {
  387. var a = t && ("load" === t.type ? "missing" : t.type)
  388. , c = t && t.target && t.target.src;
  389. i.message = "Loading chunk " + n + " failed.\n(" + a + ": " + c + ")",
  390. i.name = "ChunkLoadError",
  391. i.type = a,
  392. i.request = c,
  393. o[1](i)
  394. }
  395. }
  396. ), "chunk-" + n, n)
  397. } else
  398. e[n] = 0
  399. }
  400. ,
  401. r.O.j = function (n) {
  402. return 0 === e[n]
  403. }
  404. ;
  405. var n = function (n, t) {
  406. var o, a, c = t[0], i = t[1], f = t[2], d = 0;
  407. if (c.some((function (n) {
  408. return 0 !== e[n]
  409. }
  410. ))) {
  411. for (o in i)
  412. r.o(i, o) && (r.m[o] = i[o]);
  413. if (f)
  414. var u = f(r)
  415. }
  416. for (n && n(t); d < c.length; d++)
  417. a = c[d],
  418. r.o(e, a) && e[a] && e[a][0](),
  419. e[a] = 0;
  420. return r.O(u)
  421. }
  422. , t = window.webpackChunkJDUnion = window.webpackChunkJDUnion || [];
  423. t.forEach(n.bind(null, 0)),
  424. t.push = n.bind(null, t.push.bind(t))
  425. }(),
  426. r.nc = void 0
  427. wp = r
  428. }({
  429. 78249: function (t, n, e) {
  430. var i;
  431. t.exports = (i = i || function (t, n) {
  432. var i;
  433. if ("undefined" != typeof window && window.crypto && (i = window.crypto),
  434. "undefined" != typeof self && self.crypto && (i = self.crypto),
  435. "undefined" != typeof globalThis && globalThis.crypto && (i = globalThis.crypto),
  436. !i && "undefined" != typeof window && window.msCrypto && (i = window.msCrypto),
  437. !i && void 0 !== e.g && e.g.crypto && (i = e.g.crypto),
  438. !i)
  439. try {
  440. i = e(42480)
  441. } catch (t) {
  442. }
  443. var r = function () {
  444. if (i) {
  445. if ("function" == typeof i.getRandomValues)
  446. try {
  447. return i.getRandomValues(new Uint32Array(1))[0]
  448. } catch (t) {
  449. }
  450. if ("function" == typeof i.randomBytes)
  451. try {
  452. return i.randomBytes(4).readInt32LE()
  453. } catch (t) {
  454. }
  455. }
  456. throw new Error("Native crypto module could not be used to get secure random number.")
  457. }
  458. , s = Object.create || function () {
  459. function t() {
  460. }
  461. return function (n) {
  462. var e;
  463. return t.prototype = n,
  464. e = new t,
  465. t.prototype = null,
  466. e
  467. }
  468. }()
  469. , o = {}
  470. , u = o.lib = {}
  471. , f = u.Base = {
  472. extend: function (t) {
  473. var n = s(this);
  474. return t && n.mixIn(t),
  475. n.hasOwnProperty("init") && this.init !== n.init || (n.init = function () {
  476. n.$super.init.apply(this, arguments)
  477. }
  478. ),
  479. n.init.prototype = n,
  480. n.$super = this,
  481. n
  482. },
  483. create: function () {
  484. var t = this.extend();
  485. return t.init.apply(t, arguments),
  486. t
  487. },
  488. init: function () {
  489. },
  490. mixIn: function (t) {
  491. for (var n in t)
  492. t.hasOwnProperty(n) && (this[n] = t[n]);
  493. t.hasOwnProperty("toString") && (this.toString = t.toString)
  494. },
  495. clone: function () {
  496. return this.init.prototype.extend(this)
  497. }
  498. }
  499. , h = u.WordArray = f.extend({
  500. init: function (t, n) {
  501. t = this.words = t || [],
  502. this.sigBytes = null != n ? n : 4 * t.length
  503. },
  504. toString: function (t) {
  505. return (t || l).stringify(this)
  506. },
  507. concat: function (t) {
  508. var n = this.words
  509. , e = t.words
  510. , i = this.sigBytes
  511. , r = t.sigBytes;
  512. if (this.clamp(),
  513. i % 4)
  514. for (var s = 0; s < r; s++) {
  515. var o = e[s >>> 2] >>> 24 - s % 4 * 8 & 255;
  516. n[i + s >>> 2] |= o << 24 - (i + s) % 4 * 8
  517. }
  518. else
  519. for (var u = 0; u < r; u += 4)
  520. n[i + u >>> 2] = e[u >>> 2];
  521. return this.sigBytes += r,
  522. this
  523. },
  524. clamp: function () {
  525. var n = this.words
  526. , e = this.sigBytes;
  527. n[e >>> 2] &= 4294967295 << 32 - e % 4 * 8,
  528. n.length = t.ceil(e / 4)
  529. },
  530. clone: function () {
  531. var t = f.clone.call(this);
  532. return t.words = this.words.slice(0),
  533. t
  534. },
  535. random: function (t) {
  536. for (var n = [], e = 0; e < t; e += 4)
  537. n.push(r());
  538. return new h.init(n, t)
  539. }
  540. })
  541. , c = o.enc = {}
  542. , l = c.Hex = {
  543. stringify: function (t) {
  544. for (var n = t.words, e = t.sigBytes, i = [], r = 0; r < e; r++) {
  545. var s = n[r >>> 2] >>> 24 - r % 4 * 8 & 255;
  546. i.push((s >>> 4).toString(16)),
  547. i.push((15 & s).toString(16))
  548. }
  549. return i.join("")
  550. },
  551. parse: function (t) {
  552. for (var n = t.length, e = [], i = 0; i < n; i += 2)
  553. e[i >>> 3] |= parseInt(t.substr(i, 2), 16) << 24 - i % 8 * 4;
  554. return new h.init(e, n / 2)
  555. }
  556. }
  557. , a = c.Latin1 = {
  558. stringify: function (t) {
  559. for (var n = t.words, e = t.sigBytes, i = [], r = 0; r < e; r++) {
  560. var s = n[r >>> 2] >>> 24 - r % 4 * 8 & 255;
  561. i.push(String.fromCharCode(s))
  562. }
  563. return i.join("")
  564. },
  565. parse: function (t) {
  566. for (var n = t.length, e = [], i = 0; i < n; i++)
  567. e[i >>> 2] |= (255 & t.charCodeAt(i)) << 24 - i % 4 * 8;
  568. return new h.init(e, n)
  569. }
  570. }
  571. , d = c.Utf8 = {
  572. stringify: function (t) {
  573. try {
  574. return decodeURIComponent(escape(a.stringify(t)))
  575. } catch (t) {
  576. throw new Error("Malformed UTF-8 data")
  577. }
  578. },
  579. parse: function (t) {
  580. return a.parse(unescape(encodeURIComponent(t)))
  581. }
  582. }
  583. , p = u.BufferedBlockAlgorithm = f.extend({
  584. reset: function () {
  585. this._data = new h.init,
  586. this._nDataBytes = 0
  587. },
  588. _append: function (t) {
  589. "string" == typeof t && (t = d.parse(t)),
  590. this._data.concat(t),
  591. this._nDataBytes += t.sigBytes
  592. },
  593. _process: function (n) {
  594. var e, i = this._data, r = i.words, s = i.sigBytes, o = this.blockSize, u = s / (4 * o),
  595. f = (u = n ? t.ceil(u) : t.max((0 | u) - this._minBufferSize, 0)) * o, c = t.min(4 * f, s);
  596. if (f) {
  597. for (var l = 0; l < f; l += o)
  598. this._doProcessBlock(r, l);
  599. e = r.splice(0, f),
  600. i.sigBytes -= c
  601. }
  602. return new h.init(e, c)
  603. },
  604. clone: function () {
  605. var t = f.clone.call(this);
  606. return t._data = this._data.clone(),
  607. t
  608. },
  609. _minBufferSize: 0
  610. })
  611. , g = (u.Hasher = p.extend({
  612. cfg: f.extend(),
  613. init: function (t) {
  614. this.cfg = this.cfg.extend(t),
  615. this.reset()
  616. },
  617. reset: function () {
  618. p.reset.call(this),
  619. this._doReset()
  620. },
  621. update: function (t) {
  622. return this._append(t),
  623. this._process(),
  624. this
  625. },
  626. finalize: function (t) {
  627. return t && this._append(t),
  628. this._doFinalize()
  629. },
  630. blockSize: 16,
  631. _createHelper: function (t) {
  632. return function (n, e) {
  633. return new t.init(e).finalize(n)
  634. }
  635. },
  636. _createHmacHelper: function (t) {
  637. return function (n, e) {
  638. return new g.HMAC.init(t, e).finalize(n)
  639. }
  640. }
  641. }),
  642. o.algo = {});
  643. return o
  644. }(Math),
  645. i)
  646. },
  647. 52153: function (t, n, e) {
  648. var i;
  649. t.exports = (i = e(78249),
  650. function (t) {
  651. var n = i
  652. , e = n.lib
  653. , r = e.WordArray
  654. , s = e.Hasher
  655. , o = n.algo
  656. , u = []
  657. , f = [];
  658. !function () {
  659. function n(n) {
  660. for (var e = t.sqrt(n), i = 2; i <= e; i++)
  661. if (!(n % i))
  662. return !1;
  663. return !0
  664. }
  665. function e(t) {
  666. return 4294967296 * (t - (0 | t)) | 0
  667. }
  668. for (var i = 2, r = 0; r < 64;)
  669. n(i) && (r < 8 && (u[r] = e(t.pow(i, .5))),
  670. f[r] = e(t.pow(i, 1 / 3)),
  671. r++),
  672. i++
  673. }();
  674. var h = []
  675. , c = o.SHA256 = s.extend({
  676. _doReset: function () {
  677. this._hash = new r.init(u.slice(0))
  678. },
  679. _doProcessBlock: function (t, n) {
  680. 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++) {
  681. if (d < 16)
  682. h[d] = 0 | t[n + d];
  683. else {
  684. var p = h[d - 15]
  685. , g = (p << 25 | p >>> 7) ^ (p << 14 | p >>> 18) ^ p >>> 3
  686. , m = h[d - 2]
  687. , y = (m << 15 | m >>> 17) ^ (m << 13 | m >>> 19) ^ m >>> 10;
  688. h[d] = g + h[d - 7] + y + h[d - 16]
  689. }
  690. var v = i & r ^ i & s ^ r & s
  691. , w = (i << 30 | i >>> 2) ^ (i << 19 | i >>> 13) ^ (i << 10 | i >>> 22)
  692. ,
  693. $ = a + ((u << 26 | u >>> 6) ^ (u << 21 | u >>> 11) ^ (u << 7 | u >>> 25)) + (u & c ^ ~u & l) + f[d] + h[d];
  694. a = l,
  695. l = c,
  696. c = u,
  697. u = o + $ | 0,
  698. o = s,
  699. s = r,
  700. r = i,
  701. i = $ + (w + v) | 0
  702. }
  703. e[0] = e[0] + i | 0,
  704. e[1] = e[1] + r | 0,
  705. e[2] = e[2] + s | 0,
  706. e[3] = e[3] + o | 0,
  707. e[4] = e[4] + u | 0,
  708. e[5] = e[5] + c | 0,
  709. e[6] = e[6] + l | 0,
  710. e[7] = e[7] + a | 0
  711. },
  712. _doFinalize: function () {
  713. var n = this._data
  714. , e = n.words
  715. , i = 8 * this._nDataBytes
  716. , r = 8 * n.sigBytes;
  717. return e[r >>> 5] |= 128 << 24 - r % 32,
  718. e[14 + (r + 64 >>> 9 << 4)] = t.floor(i / 4294967296),
  719. e[15 + (r + 64 >>> 9 << 4)] = i,
  720. n.sigBytes = 4 * e.length,
  721. this._process(),
  722. this._hash
  723. },
  724. clone: function () {
  725. var t = s.clone.call(this);
  726. return t._hash = this._hash.clone(),
  727. t
  728. }
  729. });
  730. n.SHA256 = s._createHelper(c),
  731. n.HmacSHA256 = s._createHmacHelper(c)
  732. }(Math),
  733. i.SHA256)
  734. },
  735. });
  736. function ts2format(ts) {
  737. const date = new Date(ts);
  738. const y = date.getFullYear(),
  739. m = String(date.getMonth() + 1).padStart(2, '0'),
  740. d = String(date.getDate()).padStart(2, '0'),
  741. h = String(date.getHours()).padStart(2, '0'),
  742. mi = String(date.getMinutes()).padStart(2, '0'),
  743. s = String(date.getSeconds()).padStart(2, '0'),
  744. ms = String(date.getMilliseconds()).padStart(3, '0')
  745. return `${y}${m}${d}${h}${mi}${s}${ms}`;
  746. }
  747. function body(obj) {
  748. const F = wp(52153),
  749. K = wp.n(F),
  750. args_str = JSON.stringify(obj)
  751. return K()(args_str).toString()
  752. }
  753. function secret_str() {
  754. var rd = '4LP439v0MSSD';
  755. var str = "".concat(_token).concat(_fp).concat(_td).concat(_appId).concat(rd);
  756. return CryptoJS.SHA256(str).toString(CryptoJS.enc.Hex);
  757. }
  758. function encrypt_data(r, i) {
  759. function convertToQueryString(data) {
  760. return data.map(item => `${item.key}:${item.value}`).join('&');
  761. }
  762. const c = convertToQueryString(i)
  763. return CryptoJS.HmacSHA256(c, r).toString(CryptoJS.enc.Hex)
  764. }
  765. function h5st(p) {
  766. const b = body(p)
  767. const jsonArray = [
  768. {
  769. "key": "appid",
  770. "value": "unionpc"
  771. },
  772. {
  773. "key": "body",
  774. "value": b
  775. },
  776. {
  777. "key": "functionId",
  778. "value": "unionSearch"
  779. }
  780. ]
  781. const secret = secret_str()
  782. const _encrypt = encrypt_data(secret, jsonArray)
  783. const dt = "".concat(_td),
  784. fp = "".concat(_fp),
  785. appId = "".concat(_appId),
  786. tk = "".concat(_token),
  787. encrypt = "".concat(_encrypt),
  788. version = "".concat(_version),
  789. ts = "".concat(_ts),
  790. unknown = "".concat(_unknown)
  791. return [dt, fp, appId, tk, encrypt, version, ts, unknown].join(";")
  792. }
  793. e = {
  794. "funName": "search",
  795. "version": "v3",
  796. "source": 20310,
  797. "param": {
  798. "pageNo": 2,
  799. "pageSize": 60,
  800. "searchUUID": "e7fb274ce31247e689982c7375d29f5e",
  801. "bonusIds": null,
  802. "category1": null,
  803. "category2": null,
  804. "category3": null,
  805. "deliveryType": null,
  806. "wlRate": null,
  807. "maxWlRate": null,
  808. "fromPrice": null,
  809. "toPrice": null,
  810. "hasCoupon": null,
  811. "isHot": null,
  812. "isNeedPreSale": null,
  813. "isPinGou": null,
  814. "isZY": null,
  815. "isCare": null,
  816. "lock": null,
  817. "orientationFlag": null,
  818. "sort": null,
  819. "sortName": null,
  820. "keyWord": "",
  821. "searchType": "st3",
  822. "keywordType": "kt0"
  823. },
  824. "clientPageId": "jingfen_pc"
  825. }
  826. hs = h5st(e)
  827. console.log("h5st:", hs);

  1. import json
  2. import requests
  3. import execjs
  4. thor = ''
  5. _jdu = ''
  6. _3AB9D23F7A4B3CSS = ''
  7. url = "https://api.m.jd.com/api"
  8. headers = {
  9. "Accept": "application/json, text/plain, */*",
  10. "origin": "https://union.jd.com",
  11. "Referer": "https://union.jd.com/",
  12. "X-Referer-Page": "https://union.jd.com/proManager/index",
  13. "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"
  14. }
  15. cookies = {"thor": thor}
  16. class UnionJD:
  17. def __init__(self):
  18. self.js_code = execjs.compile(open('unionJD.js', 'r', encoding='utf-8').read())
  19. def get_params(self, page):
  20. params = {
  21. "functionId": "unionSearch",
  22. "appid": "unionpc",
  23. "loginType": "3",
  24. "uuid": _jdu,
  25. "x-api-eid-token": _3AB9D23F7A4B3CSS
  26. }
  27. body = {"funName": "search",
  28. "version": "v3",
  29. "source": 20310,
  30. "param": {"pageNo": page,
  31. "pageSize": 60,
  32. "searchUUID": "e47cfeb25c054a5886ca6f63449b0093",
  33. "bonusIds": None,
  34. "category1": None,
  35. "category2": None,
  36. "category3": None,
  37. "deliveryType": None,
  38. "wlRate": None,
  39. "maxWlRate": None,
  40. "fromPrice": None,
  41. "toPrice": None,
  42. "hasCoupon": None,
  43. "isHot": None,
  44. "isNeedPreSale": None,
  45. "isPinGou": None,
  46. "isZY": None,
  47. "isCare": None,
  48. "lock": None,
  49. "orientationFlag": None,
  50. "sort": None,
  51. "sortName": None,
  52. "keyWord": "",
  53. "searchType": "st3",
  54. "keywordType": "kt0"
  55. },
  56. "clientPageId": "jingfen_pc"
  57. }
  58. h5st = self.js_code.call('h5st', body)
  59. ts = h5st.split(';')[6]
  60. params['_'] = ts
  61. params['h5st'] = h5st
  62. params['body'] = json.dumps(body)
  63. return params
  64. def request_data(self, page):
  65. params = self.get_params(page)
  66. response = requests.get(url, headers=headers, cookies=cookies, params=params)
  67. return response
  68. if __name__ == '__main__':
  69. u = UnionJD()
  70. p = u.request_data(1)
  71. print(p.text)
  72. print(p.status_code)

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/675906
推荐阅读
相关标签
  

闽ICP备14008679号