qq 也可以获取支付二维码 成功微信支付了
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
"""encrypt_msg (web_new_encrypt) 生成器 — goodsBiz CHAOS VM 的纯 Python 移植
|
||||
|
||||
算法背景(见 FINDINGS.md F-2038..F-2043):
|
||||
算法背景(见 FINDINGS.md F-2038..F-2043,破解见 F-2052/2026-08-12):
|
||||
- goodsBiz.js 是腾讯 __TENCENT_CHAOS_VM 解释器(116 opcode,0..115)+ 178093 元素字节码。
|
||||
- 加密核心 = webSave h@85091(18 参):表生成 → 检查 window.xMidasOps → 33 次块变换
|
||||
(T 表 AES 类)→ 回调 h@69667(4 参)→ randGen h@85173(16 次重随机 key2)。
|
||||
- 输入:18 参(key1 诱饵 / key2 真实 / args[10]=528B 明文缓冲 / 常量表 / 回调)。
|
||||
- 输入:18 参(key1 诱饵 / key2 真实 / args[10]=16 字节对齐的明文缓冲 / 常量表 / 回调)。
|
||||
- key 派生已破解:key16 = Sbox[Te 链(key1)];服务端校验两者派生一致性,
|
||||
离线用随机 key16 + derive_key1_from_key16 反解 key1 即可通过(无需页面捕获 key)。
|
||||
- 输出:C[3476] 528 字节密文(hex 1056 字符,头部 5574bea9... 固定前缀)。
|
||||
|
||||
本文件复刻解释器语义,可在无浏览器环境运行;两组独立真实向量均 1056/1056 逐字节一致。
|
||||
@@ -660,6 +662,14 @@ class VM:
|
||||
except Exception:
|
||||
parts.append("??")
|
||||
self.out_hex = "".join(parts)
|
||||
# 仅供离线排查 webSave 输出缓冲何时变化,生产路径默认不启用。
|
||||
if getattr(self, "capture_output_lengths", False):
|
||||
v = js_index(C, 3476)
|
||||
if isinstance(v, list):
|
||||
length = len(v)
|
||||
if length != getattr(self, "_last_output_length", None):
|
||||
self._last_output_length = length
|
||||
self.output_length_trace.append((u, op, length))
|
||||
# ---- opcode dispatch ----
|
||||
if op == 0:
|
||||
a, b, c = o[u+1], o[u+2], o[u+3]; u += 3
|
||||
@@ -1461,15 +1471,18 @@ def derive_key1_from_key16(key16, te_tables=None, sbox=None):
|
||||
def generate_encrypt_msg_offline(params, fk_extend, ts, rand_val,
|
||||
key16=None, key1=None,
|
||||
args_template=None, cb_json=None,
|
||||
random_seed=None, xmidas=None, xmidas_token=None):
|
||||
random_seed=None, xmidas=None, xmidas_token=None,
|
||||
diagnostics=None):
|
||||
"""纯离线生成 encrypt_msg(A2 路线,2026-08-10 双向量 E3 闭环)。
|
||||
|
||||
params: 订单字段字典(18 字段,见 build_plaintext);fk_extend: tdrc_session 串
|
||||
(最终编码形态 tdrc_session%3Dpay-...,不再二次编码);ts: 秒级时间戳;
|
||||
rand_val: _rand 值(页面实测 8 字母数字 + 3×\\x03(run A)或 7 字母数字 +
|
||||
4×\\x04(run B),调用方自定即可);
|
||||
key16/key1: 16 字节密钥,**不影响最终输出**(E3:双向量随机密钥 1056/1056
|
||||
复现;webSave 回调内部重派生密钥,机制见 U-2030);
|
||||
key16/key1: 16 字节密钥,**不影响最终输出密文字节**(E3:双向量随机密钥 1056/1056
|
||||
复现;webSave 回调内部重派生密钥),但服务端会校验 key16 与 key1 的派生一致性
|
||||
(key16=Sbox[Te 链(key1)],F-2052),key1 必须由 derive_key1_from_key16 从 key16
|
||||
反解,不能随意给定;
|
||||
args_template: 常量表模板(跨次恒定,缺省用 work/replay/e2e/ws-args.json)。
|
||||
"""
|
||||
import random as _r
|
||||
@@ -1523,6 +1536,13 @@ def generate_encrypt_msg_offline(params, fk_extend, ts, rand_val,
|
||||
# 参数全部以 a:1 包装传入;key16 按全局块索引轮转:out[j] = word_byte[j] ^ key16[(4*blk+j)%16]
|
||||
pt = build_plaintext(params, fk_extend, ts, rand_val)
|
||||
pb = pt.encode("latin-1")
|
||||
# goods VM 只逐个处理完整的 16 字节块,不会为尾块自动填充。
|
||||
# 未对齐时继续执行会静默丢弃尾部字段,必须在请求前终止。
|
||||
if len(pb) % 16:
|
||||
raise ValueError(
|
||||
f"webSave 明文必须为 16 字节对齐,当前 {len(pb)} 字节;"
|
||||
"请用 _rand 补齐后再生成 encrypt_msg"
|
||||
)
|
||||
def _cont(*a):
|
||||
return None
|
||||
te_cap = json.loads(json.loads((replay / "e2e" / "multi-1.json").read_text().strip()))
|
||||
@@ -1562,7 +1582,18 @@ def generate_encrypt_msg_offline(params, fk_extend, ts, rand_val,
|
||||
vm.init_c = init_c
|
||||
vm.capture_at_return = True
|
||||
vm.out_hex = None
|
||||
if diagnostics is not None:
|
||||
vm.capture_output_lengths = True
|
||||
vm.output_length_trace = []
|
||||
vm._last_output_length = None
|
||||
vm.run(web, [])
|
||||
if vm.out_hex is None:
|
||||
raise RuntimeError("webSave capture failed")
|
||||
if diagnostics is not None:
|
||||
diagnostics.update({
|
||||
"plaintext_length": len(pb),
|
||||
"transform_output_length": len(outbuf),
|
||||
"ciphertext_length": len(vm.out_arr),
|
||||
"output_length_trace": vm.output_length_trace,
|
||||
})
|
||||
return vm.out_hex
|
||||
|
||||
Reference in New Issue
Block a user