specific-ai-cli 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +177 -0
  3. package/README.ja.md +177 -0
  4. package/README.ko.md +177 -0
  5. package/README.md +174 -2
  6. package/README.zh-TW.md +177 -0
  7. package/assets/banner.txt +3 -0
  8. package/dist/cli/argv.js +98 -0
  9. package/dist/cli/commands/auth.js +11 -0
  10. package/dist/cli/commands/config.js +23 -0
  11. package/dist/cli/commands/doctor.js +134 -0
  12. package/dist/cli/commands/platforms.js +24 -0
  13. package/dist/cli/commands/version.js +4 -0
  14. package/dist/cli/confirm.js +22 -0
  15. package/dist/cli/dispatch.js +440 -0
  16. package/dist/cli/help.js +223 -0
  17. package/dist/cli/hints.js +60 -0
  18. package/dist/cli/main.js +18 -0
  19. package/dist/cli/output.js +66 -0
  20. package/dist/core/auth-handlers.js +41 -0
  21. package/dist/core/auth-store.js +119 -0
  22. package/dist/core/capabilities.js +163 -0
  23. package/dist/core/config.js +121 -0
  24. package/dist/core/cookies.js +164 -0
  25. package/dist/core/errors.js +37 -0
  26. package/dist/core/files.js +89 -0
  27. package/dist/core/fsutil.js +52 -0
  28. package/dist/core/hash.js +4 -0
  29. package/dist/core/http.js +331 -0
  30. package/dist/core/image.js +280 -0
  31. package/dist/core/log.js +40 -0
  32. package/dist/core/login.js +191 -0
  33. package/dist/core/mp4.js +130 -0
  34. package/dist/core/normalize.js +207 -0
  35. package/dist/core/options.js +110 -0
  36. package/dist/core/paths.js +38 -0
  37. package/dist/core/pb.js +59 -0
  38. package/dist/core/py.js +181 -0
  39. package/dist/core/rand.js +131 -0
  40. package/dist/core/registry.js +129 -0
  41. package/dist/core/schemas.js +41 -0
  42. package/dist/core/stream.js +104 -0
  43. package/dist/core/toolkit.js +35 -0
  44. package/dist/core/vm.js +73 -0
  45. package/dist/core/vocab.js +157 -0
  46. package/dist/platforms/_shared/impaas.js +410 -0
  47. package/dist/platforms/bilibili/index.js +216 -0
  48. package/dist/platforms/bilibili/web/api.js +806 -0
  49. package/dist/platforms/bilibili/web/client.js +311 -0
  50. package/dist/platforms/bilibili/web/commands.js +783 -0
  51. package/dist/platforms/bilibili/web/ddddocr.js +342 -0
  52. package/dist/platforms/bilibili/web/gaia.js +130 -0
  53. package/dist/platforms/bilibili/web/geetest-manual.js +154 -0
  54. package/dist/platforms/bilibili/web/geetest-vision.js +232 -0
  55. package/dist/platforms/bilibili/web/geetest.js +450 -0
  56. package/dist/platforms/bilibili/web/normalize.js +234 -0
  57. package/dist/platforms/bilibili/web/profile.js +135 -0
  58. package/dist/platforms/bilibili/web/resolve.js +112 -0
  59. package/dist/platforms/bilibili/web/sign.js +223 -0
  60. package/dist/platforms/bilibili/web/upos.js +102 -0
  61. package/dist/platforms/douyin/index.js +142 -0
  62. package/dist/platforms/douyin/web/api.js +863 -0
  63. package/dist/platforms/douyin/web/client.js +413 -0
  64. package/dist/platforms/douyin/web/commands.js +712 -0
  65. package/dist/platforms/douyin/web/creator.js +601 -0
  66. package/dist/platforms/douyin/web/crypto.js +247 -0
  67. package/dist/platforms/douyin/web/dtrait.js +190 -0
  68. package/dist/platforms/douyin/web/im.js +502 -0
  69. package/dist/platforms/douyin/web/image.js +5 -0
  70. package/dist/platforms/douyin/web/live.js +225 -0
  71. package/dist/platforms/douyin/web/mssdk.js +148 -0
  72. package/dist/platforms/douyin/web/normalize.js +326 -0
  73. package/dist/platforms/douyin/web/passport.js +1247 -0
  74. package/dist/platforms/douyin/web/profile.js +221 -0
  75. package/dist/platforms/douyin/web/proto.js +26 -0
  76. package/dist/platforms/douyin/web/resolve.js +88 -0
  77. package/dist/platforms/douyin/web/sign.js +436 -0
  78. package/dist/platforms/douyin/web/tos.js +78 -0
  79. package/dist/platforms/index.js +17 -0
  80. package/dist/platforms/jd/index.js +67 -0
  81. package/dist/platforms/jd/web/aks.js +115 -0
  82. package/dist/platforms/jd/web/api.js +549 -0
  83. package/dist/platforms/jd/web/chat.js +132 -0
  84. package/dist/platforms/jd/web/client.js +470 -0
  85. package/dist/platforms/jd/web/commands.js +557 -0
  86. package/dist/platforms/jd/web/jcap/helper.js +90 -0
  87. package/dist/platforms/jd/web/jcap/host.js +107 -0
  88. package/dist/platforms/jd/web/jcap/lsd.js +300 -0
  89. package/dist/platforms/jd/web/jcap/solver.js +995 -0
  90. package/dist/platforms/jd/web/jcap.js +150 -0
  91. package/dist/platforms/jd/web/js.js +420 -0
  92. package/dist/platforms/jd/web/login.js +775 -0
  93. package/dist/platforms/jd/web/normalize.js +297 -0
  94. package/dist/platforms/jd/web/profile.js +256 -0
  95. package/dist/platforms/jd/web/util.js +175 -0
  96. package/dist/platforms/jd/web/webm.js +133 -0
  97. package/dist/platforms/kuaishou/index.js +98 -0
  98. package/dist/platforms/kuaishou/web/api.js +694 -0
  99. package/dist/platforms/kuaishou/web/captcha-crypto.js +134 -0
  100. package/dist/platforms/kuaishou/web/captcha-fp.js +180 -0
  101. package/dist/platforms/kuaishou/web/captcha.js +273 -0
  102. package/dist/platforms/kuaishou/web/client.js +487 -0
  103. package/dist/platforms/kuaishou/web/commands.js +863 -0
  104. package/dist/platforms/kuaishou/web/gap.js +144 -0
  105. package/dist/platforms/kuaishou/web/gdfp.js +376 -0
  106. package/dist/platforms/kuaishou/web/gql.js +11 -0
  107. package/dist/platforms/kuaishou/web/live.js +125 -0
  108. package/dist/platforms/kuaishou/web/normalize.js +241 -0
  109. package/dist/platforms/kuaishou/web/oracle.js +329 -0
  110. package/dist/platforms/kuaishou/web/profile.js +259 -0
  111. package/dist/platforms/kuaishou/web/resolve.js +84 -0
  112. package/dist/platforms/kuaishou/web/session.js +592 -0
  113. package/dist/platforms/kuaishou/web/sign.js +568 -0
  114. package/dist/platforms/taobao/index.js +56 -0
  115. package/dist/platforms/taobao/web/api.js +96 -0
  116. package/dist/platforms/taobao/web/client.js +102 -0
  117. package/dist/platforms/taobao/web/commands.js +172 -0
  118. package/dist/platforms/taobao/web/im.js +68 -0
  119. package/dist/platforms/taobao/web/normalize.js +103 -0
  120. package/dist/platforms/taobao/web/profile.js +85 -0
  121. package/dist/platforms/taobao/web/resolve.js +51 -0
  122. package/dist/platforms/taobao/web/sign.js +35 -0
  123. package/dist/platforms/tiktok/index.js +120 -0
  124. package/dist/platforms/tiktok/web/api.js +1234 -0
  125. package/dist/platforms/tiktok/web/client.js +362 -0
  126. package/dist/platforms/tiktok/web/commands.js +821 -0
  127. package/dist/platforms/tiktok/web/im.js +133 -0
  128. package/dist/platforms/tiktok/web/jsrun.js +126 -0
  129. package/dist/platforms/tiktok/web/normalize.js +286 -0
  130. package/dist/platforms/tiktok/web/profile.js +169 -0
  131. package/dist/platforms/tiktok/web/resolve.js +156 -0
  132. package/dist/platforms/tiktok/web/sign.js +585 -0
  133. package/dist/platforms/tiktok/web/upload.js +805 -0
  134. package/dist/platforms/tiktok/web/wire.js +490 -0
  135. package/dist/platforms/weibo/index.js +91 -0
  136. package/dist/platforms/weibo/web/api.js +206 -0
  137. package/dist/platforms/weibo/web/client.js +155 -0
  138. package/dist/platforms/weibo/web/commands.js +202 -0
  139. package/dist/platforms/weibo/web/normalize.js +137 -0
  140. package/dist/platforms/weibo/web/profile.js +246 -0
  141. package/dist/platforms/weibo/web/resolve.js +60 -0
  142. package/dist/platforms/weibo/web/sign.js +85 -0
  143. package/dist/platforms/x/index.js +107 -0
  144. package/dist/platforms/x/web/api.js +443 -0
  145. package/dist/platforms/x/web/article.js +212 -0
  146. package/dist/platforms/x/web/client.js +202 -0
  147. package/dist/platforms/x/web/commands.js +363 -0
  148. package/dist/platforms/x/web/graphql.js +108 -0
  149. package/dist/platforms/x/web/normalize.js +235 -0
  150. package/dist/platforms/x/web/profile.js +99 -0
  151. package/dist/platforms/x/web/resolve.js +44 -0
  152. package/dist/platforms/x/web/transaction.js +171 -0
  153. package/dist/platforms/xhs/index.js +101 -0
  154. package/dist/platforms/xhs/web/api.js +278 -0
  155. package/dist/platforms/xhs/web/client.js +540 -0
  156. package/dist/platforms/xhs/web/commands.js +1046 -0
  157. package/dist/platforms/xhs/web/creator-api.js +609 -0
  158. package/dist/platforms/xhs/web/creator.js +203 -0
  159. package/dist/platforms/xhs/web/js.js +194 -0
  160. package/dist/platforms/xhs/web/login.js +230 -0
  161. package/dist/platforms/xhs/web/normalize.js +166 -0
  162. package/dist/platforms/xhs/web/profile.js +127 -0
  163. package/dist/platforms/xhs/web/push.js +361 -0
  164. package/dist/platforms/xhs/web/resolve.js +69 -0
  165. package/dist/platforms/xhs/web/state.js +368 -0
  166. package/dist/platforms/xianyu/index.js +59 -0
  167. package/dist/platforms/xianyu/web/api.js +312 -0
  168. package/dist/platforms/xianyu/web/client.js +134 -0
  169. package/dist/platforms/xianyu/web/commands.js +305 -0
  170. package/dist/platforms/xianyu/web/im.js +73 -0
  171. package/dist/platforms/xianyu/web/normalize.js +123 -0
  172. package/dist/platforms/xianyu/web/profile.js +146 -0
  173. package/dist/platforms/xianyu/web/resolve.js +48 -0
  174. package/dist/platforms/xianyu/web/sign.js +79 -0
  175. package/package.json +77 -4
  176. package/static/douyin/Live.proto +194 -0
  177. package/static/douyin/Request.proto +89 -0
  178. package/static/douyin/Response.proto +46 -0
  179. package/static/douyin/acrawler_runtime/ac_vm.js +2 -0
  180. package/static/douyin/acrawler_runtime/browser_window_shape.json +1 -0
  181. package/static/douyin/acrawler_runtime/canvas_actual_exact.json +1 -0
  182. package/static/douyin/acrawler_runtime/run_ac_node.js +1005 -0
  183. package/static/douyin/acrawler_runtime/runner_window_keys_baseline.txt +240 -0
  184. package/static/douyin/challenge_profile.json +801 -0
  185. package/static/douyin/challenge_template_runner.js +217 -0
  186. package/static/douyin/dtrait_profile.json +66 -0
  187. package/static/douyin/mstoken_common_profile.json +1 -0
  188. package/static/douyin/mstoken_profile.json +214 -0
  189. package/static/jd/h5st5_env.js +750 -0
  190. package/static/jd/h5st5_lib.js +5 -0
  191. package/static/jd/h5st5_server.js +49 -0
  192. package/static/jd/jcap/env/env_core.js +512 -0
  193. package/static/jd/jcap/env/run.js +1307 -0
  194. package/static/jd/jcap/run/jcap_ujb96b.js +39 -0
  195. package/static/jd/package.json +4 -0
  196. package/static/jd/pc_tk_lib.js +1 -0
  197. package/static/jd/pc_tk_server.js +63 -0
  198. package/static/jd/summer_cryptico_runner.js +50 -0
  199. package/static/jd/webm/env/run.js +453 -0
  200. package/static/jd/webm/run/jdwebm-riskhandle.js +49 -0
  201. package/static/kuaishou/bundles/weapon/kwf-0.0.2.2cee19b4b7dec496.js +1 -0
  202. package/static/kuaishou/bundles/weapon/kws-0-0.0.1-obfuscated.4b7f3de1ab0ddcc2.js +1 -0
  203. package/static/kuaishou/bundles/weapon/kws-1-0.0.1-obfuscated.346ebdb1c78df316.js +1 -0
  204. package/static/kuaishou/bundles/weapon/kws-10-0.0.1-obfuscated.a33db41897b983af.js +1 -0
  205. package/static/kuaishou/bundles/weapon/kws-11-0.0.1-obfuscated.5e0a90af726d8a7e.js +1 -0
  206. package/static/kuaishou/bundles/weapon/kws-12-0.0.1-obfuscated.20ea29345706ec8c.js +1 -0
  207. package/static/kuaishou/bundles/weapon/kws-13-0.0.1-obfuscated.6b74e9640ff18648.js +1 -0
  208. package/static/kuaishou/bundles/weapon/kws-14-0.0.1-obfuscated.551e4429d156bf66.js +1 -0
  209. package/static/kuaishou/bundles/weapon/kws-15-0.0.1-obfuscated.8625b087aaba4a60.js +1 -0
  210. package/static/kuaishou/bundles/weapon/kws-16-0.0.1-obfuscated.d5ffa4020f3be99a.js +1 -0
  211. package/static/kuaishou/bundles/weapon/kws-17-0.0.1-obfuscated.6d13e19b22f50a80.js +1 -0
  212. package/static/kuaishou/bundles/weapon/kws-18-0.0.1-obfuscated.6d31405044166289.js +1 -0
  213. package/static/kuaishou/bundles/weapon/kws-19-0.0.1-obfuscated.a9a8d925942f19e4.js +1 -0
  214. package/static/kuaishou/bundles/weapon/kws-2-0.0.1-obfuscated.b849a136ae4a6b3e.js +1 -0
  215. package/static/kuaishou/bundles/weapon/kws-3-0.0.1-obfuscated.f9e77ebf6186e2ac.js +1 -0
  216. package/static/kuaishou/bundles/weapon/kws-4-0.0.1-obfuscated.2c3c155aa52ceb0e.js +1 -0
  217. package/static/kuaishou/bundles/weapon/kws-5-0.0.1-obfuscated.4e553d17691b3c5a.js +1 -0
  218. package/static/kuaishou/bundles/weapon/kws-6-0.0.1-obfuscated.f73ddd3ff13e1217.js +1 -0
  219. package/static/kuaishou/bundles/weapon/kws-7-0.0.1-obfuscated.1628b8729beaab7e.js +1 -0
  220. package/static/kuaishou/bundles/weapon/kws-8-0.0.1-obfuscated.6da6baef7aa81fff.js +1 -0
  221. package/static/kuaishou/bundles/weapon/kws-9-0.0.1-obfuscated.8645d55e5323b743.js +1 -0
  222. package/static/kuaishou/fixtures/current_follow_script_813.network-response +2 -0
  223. package/static/kuaishou/fixtures/live_ws_maps.json +61 -0
  224. package/static/kuaishou/fixtures/live_ws_proto.json +1342 -0
  225. package/static/kuaishou/js/cp-kwf.js +1 -0
  226. package/static/kuaishou/tools/kwf_oracle.js +799 -0
  227. package/static/kuaishou/tools/kws_oracle.js +885 -0
  228. package/static/kuaishou/tools/like_token_oracle.js +70 -0
  229. package/static/taobao/taobao_js_20260407.js +570 -0
  230. package/static/tiktok/Tiktok_Request.json +597 -0
  231. package/static/tiktok/package.json +3 -0
  232. package/static/tiktok/shop_bsid/core.js +1 -0
  233. package/static/tiktok/shop_bsid/env_core.js +512 -0
  234. package/static/tiktok/shop_bsid/loader.js +1 -0
  235. package/static/tiktok/shop_bsid/run.js +753 -0
  236. package/static/tiktok/shop_bsid/sign.js +100 -0
  237. package/static/tiktok/shop_bsid/webmssdk.js +1 -0
  238. package/static/tiktok/shop_bsid/webmssdk_ex.js +1 -0
  239. package/static/tiktok/signing/env/env_core.js +512 -0
  240. package/static/tiktok/signing/env/sign.js +455 -0
  241. package/static/tiktok/signing/sdk_config.json +230 -0
  242. package/static/tiktok/signing/source/webmssdk.js +1 -0
  243. package/static/tiktok/signing/source/webmssdk_ex.js +1 -0
  244. package/static/tiktok/signing/source/webmssdk_legacy.js +1 -0
  245. package/static/x/graphql.json +7777 -0
  246. package/static/x/transaction_l1.json +12 -0
  247. package/static/xhs/package.json +3 -0
  248. package/static/xhs/xhs_core/js/b1.js +210 -0
  249. package/static/xhs/xhs_core/js/mns.js +340 -0
  250. package/static/xhs/xhs_core/js/mns_0101_keystream.json +5 -0
  251. package/static/xhs/xhs_core/js/mns_keystreams.json +1 -0
  252. package/static/xhs/xhs_core/js/sign.js +225 -0
  253. package/static/xhs/xhs_core/js/websectiga_cli.js +220 -0
  254. package/static/xhs/xhs_core/js/websectiga_env.js +512 -0
  255. package/static/xhs/xhs_core/js/xs_common.js +79 -0
  256. package/static/xhs/xhs_creator/js/profile.js +115 -0
  257. package/static/xhs/xhs_creator/js/rap_fingerprint_creator.json +6 -0
  258. package/static/xhs/xhs_creator/js/reference_profile.json +282 -0
  259. package/static/xhs/xhs_creator/js/xhs_creator_sign.js +29 -0
  260. package/static/xhs/xhs_creator/js/xhs_creator_signature.js +23 -0
  261. package/static/xhs/xhs_pc/js/aes_decrypt.js +22 -0
  262. package/static/xhs/xhs_pc/js/aes_encrypt.js +30 -0
  263. package/static/xhs/xhs_pc/js/b1.js +9 -0
  264. package/static/xhs/xhs_pc/js/deflate.js +320 -0
  265. package/static/xhs/xhs_pc/js/mns.js +4 -0
  266. package/static/xhs/xhs_pc/js/profile.js +141 -0
  267. package/static/xhs/xhs_pc/js/rap.js +173 -0
  268. package/static/xhs/xhs_pc/js/rap_cli.js +30 -0
  269. package/static/xhs/xhs_pc/js/rap_crypto.js +73 -0
  270. package/static/xhs/xhs_pc/js/rap_fingerprint_template.json +8 -0
  271. package/static/xhs/xhs_pc/js/reference_profile.json +262 -0
  272. package/static/xhs/xhs_pc/js/sign.js +6 -0
  273. package/static/xhs/xhs_pc/js/web_ssk.js +82 -0
  274. package/static/xhs/xhs_pc/js/xs_common.js +4 -0
  275. package/static/xianyu/et_f.js +2 -0
  276. package/static/xianyu/gen_tfstk.js +410 -0
  277. package/static/xianyu/goofish_js_version_2.js +568 -0
@@ -0,0 +1,73 @@
1
+ /**
2
+ * x-rap-param 纯算 —— 加密侧(crypto + 信封),零补环境。
3
+ * 管线:payload → gzip(pure XHS) → alphabet36-random-pad → XOR(xorKey) → AES-128-ECB(自研S-box, 固定密钥) → body
4
+ * encR = AES-128-ECB(xorKey)
5
+ * 信封 = header + nonce + encR + len + body + trailing(bodyLen)
6
+ * 分组密码 = 标准 AES-128-ECB,仅 S-box 换成小红书自研表。
7
+ * DEFLATE = deflate.js(简单贪婪LZ77 + 动态Huffman,字节对齐浏览器版本)。
8
+ */
9
+ 'use strict';
10
+ const crypto = require('crypto');
11
+ const zlib = require('zlib');
12
+ const { aesEncBlock } = require('./aes_encrypt.js');
13
+ const { aesDecBlock } = require('./aes_decrypt.js');
14
+ const { encodeGzip } = require('./deflate.js');
15
+
16
+ const SBOX = [122,1,88,224,80,78,2,121,29,75,83,218,107,72,212,82,237,119,18,33,20,21,236,16,24,229,185,241,12,8,252,125,249,205,181,200,230,55,38,135,86,186,184,43,173,240,104,247,139,141,211,94,54,77,46,146,49,130,242,41,112,61,45,215,182,64,178,67,68,128,120,210,13,73,74,9,99,108,7,58,158,213,6,198,225,98,244,52,36,89,169,87,42,0,62,23,44,10,26,66,250,147,190,220,245,179,106,19,232,3,199,151,187,115,118,134,227,70,114,71,208,5,76,56,124,31,129,171,117,81,235,243,50,116,17,143,132,137,156,113,34,126,157,207,63,145,105,101,60,109,150,162,152,153,51,57,154,202,195,159,160,188,228,163,164,84,127,167,168,4,111,93,172,183,39,175,176,40,65,174,180,110,11,27,223,142,48,177,254,144,97,96,192,203,92,14,239,22,131,234,32,233,201,85,196,69,133,204,30,170,103,138,123,53,214,25,216,217,194,219,148,221,28,222,166,255,248,191,91,90,15,231,193,189,209,102,197,37,238,140,226,95,136,161,59,165,246,206,149,47,100,35,251,253,79,155];
17
+ const AES_KEY = [...Buffer.from('kqI1DTcwKX90ZtAy')];
18
+ const ALPHABET36 = '0123456789abcdefghijklmnopqrstuvwxyz';
19
+
20
+ function aesEcbEnc(data) { const o = []; for (let i = 0; i < data.length; i += 16) o.push(...aesEncBlock([...data.slice(i, i + 16)], AES_KEY.slice(), SBOX)); return Buffer.from(o); }
21
+ function aesEcbDec(data) { const o = []; for (let i = 0; i + 16 <= data.length; i += 16) o.push(...aesDecBlock([...data.slice(i, i + 16)], AES_KEY.slice(), SBOX)); return Buffer.from(o); }
22
+
23
+ // XHS 使用 alphabet36 随机 ASCII 填充到 16 字节边界 (NOT PKCS7)
24
+ function alpha36Pad(buf) {
25
+ const n = 16 - (buf.length % 16);
26
+ const padActual = n === 0 ? 16 : n;
27
+ const rand = crypto.randomBytes(padActual);
28
+ const padBytes = Buffer.from([...rand].map(b => ALPHABET36.charCodeAt(b % 36)));
29
+ return Buffer.concat([buf, padBytes]);
30
+ }
31
+
32
+ function pkcs7(buf) { const n = 16 - (buf.length % 16); return Buffer.concat([buf, Buffer.alloc(n, n)]); }
33
+
34
+ // 加密:payload(Buffer) + xorKey(16B) → {encR, body, gzipLen}
35
+ // mtime 可选:想字节对齐浏览器需要提供 mtime 与 xorKey,padBytes(可选)覆盖随机填充
36
+ function encryptPayload(payload, xorKey, opts = {}) {
37
+ let gz;
38
+ try {
39
+ gz = encodeGzip(payload, opts.mtime || 0);
40
+ } catch (err) {
41
+ // 大 payload(如 Creator 发布的 452B 指纹)会让自研 Huffman 树深超过 15
42
+ // 触发 overflow;回退 Node zlib 裸 deflate(与浏览器同族的合法编码,
43
+ // 服务端只做 AES-ECB + XOR + gunzip 校验,不逐字节比对 deflate)。
44
+ const deflated = zlib.deflateRawSync(payload, { level: 9 });
45
+ const mtime = opts.mtime || 0;
46
+ gz = Buffer.alloc(10 + deflated.length + 8);
47
+ gz[0] = 0x1f; gz[1] = 0x8b; gz[2] = 0x08; gz[3] = 0x00;
48
+ gz.writeUInt32LE(mtime, 4);
49
+ gz[8] = 0x00; gz[9] = 0x03;
50
+ deflated.copy(gz, 10);
51
+ gz.writeUInt32LE(zlib.crc32(payload), 10 + deflated.length);
52
+ gz.writeUInt32LE(payload.length & 0xffffffff, 14 + deflated.length);
53
+ }
54
+ const gzipLen = gz.length;
55
+ const padded = opts.padBytes
56
+ ? Buffer.concat([gz, Buffer.from(opts.padBytes)])
57
+ : alpha36Pad(gz);
58
+ const xored = Buffer.from(padded.map((b, i) => b ^ xorKey[i % 16]));
59
+ const body = aesEcbEnc(xored);
60
+ const encR = aesEcbEnc(Buffer.from(xorKey));
61
+ return { encR, body, gzipLen };
62
+ }
63
+
64
+ // 解密(验证用)— 通过尝试不同尾部长度找出 gzip 结束位置
65
+ function decryptBody(encR, body) {
66
+ const xorKey = aesEcbDec(encR);
67
+ const xored = aesEcbDec(body);
68
+ const gz = Buffer.from(xored.map((b, i) => b ^ xorKey[i % 16]));
69
+ for (let trim = 0; trim <= 16; trim++) { try { return zlib.gunzipSync(gz.slice(0, gz.length - trim)); } catch (e) {} }
70
+ throw new Error('gunzip failed');
71
+ }
72
+
73
+ module.exports = { encryptPayload, decryptBody, aesEcbEnc, aesEcbDec, SBOX, AES_KEY, pkcs7, alpha36Pad };
@@ -0,0 +1,8 @@
1
+ {
2
+ "captured": "2026-07-14",
3
+ "source": "capture_20260714.json sample[1] (homefeed 235B)",
4
+ "mask": "0x38",
5
+ "plLen": 235,
6
+ "bodyLen": 219,
7
+ "bodyUnmaskedHex": "03ea00000010346c326b326a6a673668696d6472366203ebb0037bbb041b00041c00041d00041e00041f00042000042100042200042300042400042500042600042700042800042900042e00042a00042b00042c00042d00044c00000000042f00043000043100043600000000043a00000000043c00000000044000000000044200000000044900000012000000019f615912f2010000019f617b376d044400000a000446000004f704470000019f615908a50445000000000448000443000000040012ffff048400048500000000048000048100048200048300"
8
+ }
@@ -0,0 +1,262 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "source": "xhs-pc-browser-fixtures-20260718",
4
+ "release": {
5
+ "appId": "xhs-pc-web",
6
+ "platform": "Windows",
7
+ "signVersion": "4.4.3",
8
+ "b1SdkVersion": "3.5.4",
9
+ "webProfileSdkVersion": "4.4.3",
10
+ "webBuild": "6.47.2",
11
+ "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36",
12
+ "secChUa": "\"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"152\", \"Google Chrome\";v=\"152\""
13
+ },
14
+ "b1Reference": {
15
+ "frameCount": 2,
16
+ "x39": 22,
17
+ "x50": "131,88,103",
18
+ "secCanvas": "__SEC_CAV__1-1-1-1-1|",
19
+ "timeOriginOffsetMs": -2027.8,
20
+ "telemetryProfile": "active",
21
+ "selectedGlobalNames": [
22
+ "_BHjFmfUMEtxhI",
23
+ "_AUuXfEG27Xa3x",
24
+ "__xhsPendingNotePoint25300ReportMap",
25
+ "__xhsReportedNotePoint25300RecordMap",
26
+ "setImDebugMode",
27
+ "anti_hp_sign_config",
28
+ "__rap_app_id__",
29
+ "__rap_report__",
30
+ "__rap_last_sign_cost__",
31
+ "__rap_last_transform_cost__",
32
+ "__rap_hijack_installed__",
33
+ "__ed1a7dddf7c818e4bd",
34
+ "__hp_xhs_search_input_state__",
35
+ "__hp_xhs_search_submit_state__"
36
+ ],
37
+ "mouse": {
38
+ "me": 50,
39
+ "mm": 50,
40
+ "md": 3,
41
+ "mu": 3,
42
+ "c": 3,
43
+ "dc": 1
44
+ },
45
+ "keyboard": {},
46
+ "page": {
47
+ "ulr": 5,
48
+ "ps": 1,
49
+ "f": 20,
50
+ "b": 19,
51
+ "vc": 2,
52
+ "rs": 1,
53
+ "sc": 1
54
+ },
55
+ "state": {
56
+ "h": 0,
57
+ "f": 1,
58
+ "kr": 0
59
+ },
60
+ "features": {
61
+ "ae": 2.8905690597867015,
62
+ "ak": 5.664426623996462,
63
+ "cdr": 0.15566784512304102,
64
+ "bf": {
65
+ "ar": 0.9785478547854786,
66
+ "fr": 6.242728437964205
67
+ },
68
+ "fi": 3363
69
+ }
70
+ },
71
+ "b1Profiles": {
72
+ "login": {
73
+ "frameCount": 2,
74
+ "x39": 0,
75
+ "x50": "",
76
+ "generatedAtOffsetMs": 1839,
77
+ "secCanvas": "__SEC_CAV__1-1-1-1-1|__SEC_UD__|",
78
+ "timeOriginOffsetMs": -791.9,
79
+ "telemetryProfile": "login",
80
+ "telemetryTemplate": "{mt:{to:__TIME_ORIGIN__},m:{},k:{},p:{ulr:0,rs:1,ps:1,f:1},st:{h:0,f:1,kr:0},ft:{ae:null,ak:null,cdr:null,bf:null,fi:null}}",
81
+ "x37": "0|0|0|0|0|0|0|0|0|1|0|0|0|0|0|0|0|0|1|0|0|0|0|0",
82
+ "x38": "0|0|1|0|1|0|0|0|0|0|1|0|1|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0",
83
+ "x82": "1|_BHjFmfUMEtxhI|_AUuXfEG27Xa3x|__xhsPendingNotePoint25300ReportMap|__xhsReportedNotePoint25300RecordMap|setImDebugMode|anti_hp_sign_config|__rap_app_id__|__rap_report__|__rap_last_sign_cost__|__rap_last_transform_cost__|__rap_hijack_installed__|__ed1a7dddf7c818e4bd|__hp_xhs_search_input_state__|__h",
84
+ "evidence": "Fresh isolated PC login page6 webprofile collector on 2026-07-19"
85
+ }
86
+ },
87
+ "webProfile": {
88
+ "algorithm": "base64-des-ecb-zero-padding-hex",
89
+ "i12Seed": 70,
90
+ "i12DynamicIndexes": [],
91
+ "telemetryFi": 326,
92
+ "timeOriginOffsetMs": -791.9,
93
+ "telemetryTemplate": "{mt:{to:__TIME_ORIGIN__},m:{},k:{},p:{ulr:0,rs:1,ps:1,f:1},st:{h:0,f:1,kr:0},ft:{ae:null,ak:null,cdr:null,bf:null,fi:null}}",
94
+ "fields": {
95
+ "x1": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36",
96
+ "x2": "false",
97
+ "x3": "zh-CN",
98
+ "x4": "24",
99
+ "x5": "32",
100
+ "x6": "24",
101
+ "x7": "Google Inc. (NVIDIA),ANGLE (NVIDIA, NVIDIA GeForce RTX 5060 Ti (0x00002D04) Direct3D11 vs_5_0 ps_5_0, D3D11)",
102
+ "x8": "20",
103
+ "x9": "2560;1440",
104
+ "x10": "2560;1392",
105
+ "x11": "-480",
106
+ "x12": "Asia/Shanghai",
107
+ "x13": "true",
108
+ "x14": "true",
109
+ "x15": "true",
110
+ "x16": "false",
111
+ "x17": "false",
112
+ "x18": "un",
113
+ "x19": "Win32",
114
+ "x20": "un",
115
+ "x21": "PDF Viewer,Chrome PDF Viewer,Chromium PDF Viewer,Microsoft Edge PDF Viewer,WebKit built-in PDF",
116
+ "x22": "c8e2f6ff2a07957f70a18cde6b905ebb",
117
+ "x23": "false",
118
+ "x24": "false",
119
+ "x25": "false",
120
+ "x26": "false",
121
+ "x27": "false",
122
+ "x28": "10,false,false",
123
+ "x29": "4,7,8",
124
+ "x30": "swf object not loaded",
125
+ "x31": "124.04347527516074",
126
+ "x33": "0",
127
+ "x34": "0",
128
+ "x35": "0",
129
+ "x36": "2",
130
+ "x37": "0|0|0|0|0|0|0|0|0|1|0|0|0|0|0|0|0|0|1|0|0|0|0|0",
131
+ "x38": "0|0|1|0|1|0|0|0|0|0|1|0|1|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0",
132
+ "x39": "0",
133
+ "x40": "0",
134
+ "x41": "0",
135
+ "x42": "3.5.4",
136
+ "x43": "Canvas not supported",
137
+ "x44": "1784388700729",
138
+ "x45": "__SEC_CAV__1-1-1-1-1|__SEC_UD__|",
139
+ "x46": "false",
140
+ "x47": "1|0|0|0|0|0",
141
+ "x48": "",
142
+ "x49": "{list:[],type:}",
143
+ "x50": "",
144
+ "x51": "",
145
+ "x52": "",
146
+ "x54": "11311144241322244122",
147
+ "x55": "280,300,280,260,280,280,260,280,240,280,280,340,260,320",
148
+ "x56": "Google Inc. (NVIDIA)|ANGLE (NVIDIA, NVIDIA GeForce RTX 5060 Ti (0x00002D04) Direct3D11 vs_5_0 ps_5_0, D3D11)|0ebc53d03ea89d69525d81de558e2544|35",
149
+ "x53": "993da9a681fd3994c9f53de11f2903b3",
150
+ "x57": "ets=1784388696387; domain=.xiaohongshu.com; path=/; max-age=2592000",
151
+ "x58": "251",
152
+ "x59": "47",
153
+ "x60": "63",
154
+ "x61": "1352",
155
+ "x62": "2047",
156
+ "x63": "0",
157
+ "x64": "0",
158
+ "x65": "0",
159
+ "x66": {
160
+ "referer": "",
161
+ "location": "https://www.xiaohongshu.com/explore",
162
+ "frame": 0
163
+ },
164
+ "x67": "1|0",
165
+ "x68": "0",
166
+ "x69": "un",
167
+ "x70": [
168
+ "location",
169
+ "getElementById",
170
+ "getElementsByTagName",
171
+ "querySelector",
172
+ "querySelectorAll",
173
+ "evaluate"
174
+ ],
175
+ "x71": "true",
176
+ "x72": "complete",
177
+ "x73": "1800",
178
+ "x74": "0|0|0",
179
+ "x75": "Google Inc.",
180
+ "x76": "true",
181
+ "x77": "1|1|1|1|1|1|1|1|1|1",
182
+ "x78": {
183
+ "x": 0,
184
+ "y": 2598.9375,
185
+ "left": 0,
186
+ "right": 290.828125,
187
+ "bottom": 2616.9375,
188
+ "height": 18,
189
+ "top": 2598.9375,
190
+ "width": 290.828125,
191
+ "font": "system-ui, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\", -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, BlinkMacSystemFont, \"Helvetica Neue\", Arial, \"PingFang SC\", \"PingFang TC\", \"PingFang HK\", \"Microsoft Yahei\", \"Microsoft JhengHei\""
192
+ },
193
+ "x79": "14442|6442465386",
194
+ "x80": "1|[object FileSystemDirectoryHandle]",
195
+ "x82": "1|_BHjFmfUMEtxhI|_AUuXfEG27Xa3x|__xhsPendingNotePoint25300ReportMap|__xhsReportedNotePoint25300RecordMap|setImDebugMode|anti_hp_sign_config|__rap_app_id__|__rap_report__|__rap_last_sign_cost__|__rap_last_transform_cost__|__rap_hijack_installed__|__ed1a7dddf7c818e4bd|__hp_xhs_search_input_state__|__h",
196
+ "x83": "eyJkIjp7IjAiOjEzMiwiMSI6MTYyLCIyIjoxMDksIjMiOjExNiwiNCI6MTI5LCI1IjoxNjIsIjYiOjExNiwiNyI6MTExLCI4IjoyMDMsIjkiOjY2LCIxMCI6MTIxLCIxMSI6MjQ3LCIxMiI6MTU4LCIxMyI6MTQ0LCIxNCI6MTQ1LCIxNSI6ODEsIjE2IjoxNTQsIjE3IjoxNjEsIjE4IjoxMDksIjE5IjoxMjgsIjIwIjoxNjEsIjIxIjoxMDcsIjIyIjoxMjgsIjIzIjoxNjEsIjI0IjoxMTIsIjI1IjoxMzIsIjI2IjoxNjMsIjI3IjoxMTcsIjI4IjoxMDgsIjI5IjoxMTQsIjMwIjoxNDQsIjMxIjoxNjIsIjMyIjoxMTQsIjMzIjoxMTUsIjM0IjoxNDUsIjM1IjoxMzEsIjM2IjoxNjIsIjM3IjoxMTYsIjM4IjoxMTUsIjM5IjoyMDUsIjQwIjoyLCI0MSI6MTUwLCI0MiI6MTYxLCI0MyI6MTA0LCI0NCI6MTk0LCI0NSI6MTYxLCI0NiI6MTAyLCI0NyI6MTk1LCI0OCI6MTYyLCI0OSI6MTEyLCI1MCI6MTE1LCI1MSI6MTQ1LCI1MiI6MTMxLCI1MyI6MTYyLCI1NCI6MTE2LCI1NSI6MTE1LCI1NiI6MjA1LCI1NyI6NSwiNTgiOjU1LCI1OSI6MTYxLCI2MCI6MTA0LCI2MSI6MTk0LCI2MiI6MTYxLCI2MyI6MTAyLCI2NCI6MTk1LCI2NSI6MTYxLCI2NiI6MTAyLCI2NyI6MTQ1LCI2OCI6MTMxLCI2OSI6MTYyLCI3MCI6MTE2LCI3MSI6MTE1LCI3MiI6MjA1LCI3MyI6NywiNzQiOjU3LCI3NSI6MTYxLCI3NiI6MTA0LCI3NyI6MTk0LCI3OCI6MTYxLCI3OSI6MTAyLCI4MCI6MTk1fSwidiI6MSwiZSI6Im0ifQ==",
197
+ "x84": "{mt:{to:1784456743189.1},m:{},k:{},p:{ulr:0,rs:1,ps:1,f:1},st:{h:0,f:1,kr:0},ft:{ae:null,ak:null,cdr:null,bf:null,fi:null}}"
198
+ }
199
+ },
200
+ "mnsStages": {
201
+ "security": {
202
+ "tier": "0201",
203
+ "envConst": 1315,
204
+ "envFpTailHex": "f8536767c9b581635e0744fa8415",
205
+ "evidence": "cold-start seq 1-4, four browser fixtures byte-exact"
206
+ },
207
+ "coldContent": {
208
+ "tier": "0101",
209
+ "envConst": 1327,
210
+ "envFpTailHex": "f9536767c9b581635e0744fa8415",
211
+ "evidence": "cold-start seq 5-10, six browser fixtures byte-exact"
212
+ },
213
+ "steadyContent": {
214
+ "tier": "0301",
215
+ "envConst": 1352,
216
+ "envFpTailHex": "f9416767c9b581635e0744fa8415",
217
+ "evidence": "Fresh isolated PC login page6 webprofile x61; runtime-state dependent"
218
+ }
219
+ },
220
+ "loginMnsProfiles": {
221
+ "security_initial": {
222
+ "tier": "0201",
223
+ "envConst": 1322,
224
+ "envFpTailHex": "f8536767c9b581635e0744fa8415",
225
+ "evidence": "Fresh isolated Chrome 152 PC login security chain, 2026-09-06"
226
+ },
227
+ "security_callback": {
228
+ "tier": "0101",
229
+ "envConst": 1332,
230
+ "envFpTailHex": "f9526767c9b581635e0744fa8415",
231
+ "evidence": "Fresh isolated Chrome 152 PC seccallback, 2026-09-06"
232
+ },
233
+ "activate": {
234
+ "tier": "0101",
235
+ "envConst": 1335,
236
+ "envFpTailHex": "f9526767c9b581635e0744fa8415",
237
+ "evidence": "Fresh isolated Chrome 152 PC login activation, 2026-09-06"
238
+ },
239
+ "qrcode_create": {
240
+ "tier": "0301",
241
+ "envConst": 1350,
242
+ "envFpTailHex": "f9416767c9b581635e0744fa8415",
243
+ "evidence": "Fresh isolated Chrome 152 PC QR creation, 2026-09-06"
244
+ },
245
+ "qrcode_poll": {
246
+ "tier": "0301",
247
+ "envConst": 1351,
248
+ "envFpTailHex": "f9416767c9b581635e0744fa8415",
249
+ "evidence": "Fresh isolated Chrome 152 PC QR polling, 2026-09-06"
250
+ },
251
+ "webprofile": {
252
+ "tier": "0301",
253
+ "envConst": 1358,
254
+ "envFpTailHex": "f9416767c9b581635e0744fa8415",
255
+ "evidence": "Fresh isolated Chrome 152 PC webprofile, 2026-09-06"
256
+ }
257
+ },
258
+ "rap": {
259
+ "fingerprintVersion": 10301,
260
+ "fingerprintTemplate": "rap_fingerprint_template.json"
261
+ }
262
+ }
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ // Legacy PC CLI path; the algorithm is maintained under xhs_core/js.
4
+ const impl = require('../../xhs_core/js/sign.js');
5
+ if (require.main === module && typeof impl.main === 'function') impl.main();
6
+ module.exports = impl;
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+
3
+ const crypto = require('crypto');
4
+
5
+ const X25519_PKCS8_PREFIX = Buffer.from('302e020100300506032b656e04220420', 'hex');
6
+ const X25519_SPKI_PREFIX = Buffer.from('302a300506032b656e032100', 'hex');
7
+ const SERVER_PUBLIC_KEY = Buffer.from(
8
+ 'Kr0iygsCu3inYJNXCL4k4JuzaYQ2afI1xbwc7BH6sm8=',
9
+ 'base64',
10
+ );
11
+
12
+ function privateKeyFromRaw(raw) {
13
+ const value = Buffer.from(raw);
14
+ if (value.length !== 32) throw new Error('X25519 private key must be 32 bytes');
15
+ return crypto.createPrivateKey({
16
+ key: Buffer.concat([X25519_PKCS8_PREFIX, value]),
17
+ format: 'der',
18
+ type: 'pkcs8',
19
+ });
20
+ }
21
+
22
+ function publicKeyFromRaw(raw) {
23
+ const value = Buffer.from(raw);
24
+ if (value.length !== 32) throw new Error('X25519 public key must be 32 bytes');
25
+ return crypto.createPublicKey({
26
+ key: Buffer.concat([X25519_SPKI_PREFIX, value]),
27
+ format: 'der',
28
+ type: 'spki',
29
+ });
30
+ }
31
+
32
+ function createHandshake() {
33
+ const { privateKey, publicKey } = crypto.generateKeyPairSync('x25519');
34
+ const privateDer = privateKey.export({ format: 'der', type: 'pkcs8' });
35
+ const publicDer = publicKey.export({ format: 'der', type: 'spki' });
36
+ return {
37
+ private_key_base64: privateDer.subarray(-32).toString('base64'),
38
+ client_public_key_base64: publicDer.subarray(-32).toString('base64'),
39
+ };
40
+ }
41
+
42
+ function acceptSsk(privateKeyBase64, encryptedSskBase64, serverPublicKey = SERVER_PUBLIC_KEY) {
43
+ const privateKey = privateKeyFromRaw(Buffer.from(String(privateKeyBase64), 'base64'));
44
+ const publicKey = publicKeyFromRaw(Buffer.from(serverPublicKey));
45
+ const sharedSecret = crypto.diffieHellman({ privateKey, publicKey });
46
+ const encrypted = Buffer.from(String(encryptedSskBase64), 'base64');
47
+ if (encrypted.length < 12 + 16) throw new Error('encrypted SSK is truncated');
48
+ const nonce = encrypted.subarray(0, 12);
49
+ const payload = encrypted.subarray(12);
50
+ const ciphertext = payload.subarray(0, -16);
51
+ const tag = payload.subarray(-16);
52
+ const decipher = crypto.createDecipheriv('aes-256-gcm', sharedSecret, nonce);
53
+ decipher.setAuthTag(tag);
54
+ const plain = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
55
+ if (plain.length < 32) throw new Error('decrypted SSK is too short');
56
+ return plain.toString('base64');
57
+ }
58
+
59
+ function main() {
60
+ const input = JSON.parse(process.argv[2] || '{}');
61
+ if (input.action === 'create') {
62
+ process.stdout.write(JSON.stringify(createHandshake()) + '\n');
63
+ return;
64
+ }
65
+ if (input.action === 'accept') {
66
+ process.stdout.write(JSON.stringify({
67
+ ssk_base64: acceptSsk(input.private_key_base64, input.encrypted_ssk_base64),
68
+ }) + '\n');
69
+ return;
70
+ }
71
+ throw new Error('action must be create or accept');
72
+ }
73
+
74
+ if (require.main === module) main();
75
+
76
+ module.exports = {
77
+ SERVER_PUBLIC_KEY,
78
+ createHandshake,
79
+ acceptSsk,
80
+ privateKeyFromRaw,
81
+ publicKeyFromRaw,
82
+ };
@@ -0,0 +1,4 @@
1
+ 'use strict';
2
+
3
+ // Legacy PC path kept in sync with the maintained pure implementation.
4
+ module.exports = require('../../xhs_core/js/xs_common.js');