# 密钥总账 — 996传奇盒子 + 传奇游戏客户端 全量密钥盘点 > 盘点日期: 2026-09-23 > 目的: 回答"梳理过程中可有密钥没有梳理出来"——对两个客户端全部密钥/凭据做穷举清点, > 逐项标注【已提取/已定论/新增】状态, 并记录本轮新发现。 > 配套: 《Lua脚本解密说明与壳层SDK逆向细节.md》《rsa_investigation.md》《996传奇盒子结构与启动机制分析.md》 --- ## 一、游戏客户端 (mod_fgcq / mod_launcher, C++ 层) ### 1.1 XXTEA key/sign 注册表 — ★本轮新增一组 初始化函数 `0x100043bdc` 向注册表 (`std::map`, 写函数 `0x10025493c`) 注册**两组** key/sign, 此前文档只记录了 XOR 混淆那组, **第二组(明文直用)是本轮反汇编新发现**: | 组 | key | sign (XXTEA 8B 头) | 存放形态 | 验证 | |---|---|---|---|---| | ① 主组 (本包在用) | `34UFXMgtkz` | `4meJnPyl` | XOR 0x10 混淆 @0x6c60a6/0x6c60b1 | ✅ 实测解密 main.lua 全明文 | | ② 副组 (渠道备用) | `9V8N6QngLT` | `!yscqzip` | **明文** @0x6c60ba/0x6c60c5 (直传, 无解混淆调用) | ✗ 用其解本包 lua 失败 → 非本包 key, 系多渠道注册表条目 | | 备用字面量 | `wVTx3dT01j` / `XdvFTgd5YA` | — | XOR 0x10 @0x6c60ce/0x6c60d9 | 实测解密失败, 疑其他渠道包轮换值 | 反汇编证据 (0x100043d84 起): ``` ; 组② 无任何 100043b34(XOR解混淆) 调用, 直接: ldr x8, [0x1006c60ba] ; '9V8N6Qng' 前 8B mov w8, #0x4c67; movk w8, #0x54, lsl 16 ; 拼 'g' 'L' 'T' → 共 11B '9V8N6QngLT' ldr x8, [0x1006c60c5] ; '!yscqzip' 8B bl 0x10025493c ; register(single, key, sign) ``` GM 动态换 key (`SetXXTEAKeyGM`, 0x100044b88) 走同一注册函数, 机制不变: `new_key = X + "2Gm" + X + "V3GMWeFly"`。 ### 1.2 已定论 (无密钥可挖) | 项 | 结论 | |---|---| | RSA (LuaBridgeCtl:RsaEncryptPub/DecryptPri) | **空壳 stub**, 二进制无任何密钥材料, 证据链见 `rsa_investigation.md` | | 反作弊水印 Sequence 表 | 非 key, 是 `{NetStampHost}/{MD5(serverID)}.txt` 按时间索引的服务端下发值 | | Encode6BitBuf 头编码 | 编码表 256B @`__DATA 0x1008ae5f4` 已提取 (`hdr_codec.py` roundtrip ✓) | | 游戏服 TCP 会话密钥 | SC529 服务端**每次登录动态下发** key32, 客户端原样回传 (protocol_bot `cq2_pure_enter.py` 已实现), 非静态常量 | ### 1.3 疑似常量定性 (本轮新查, 非密钥) 两条形似 key 的字面量 (spine 动画资源模块 `0x1000582f8/0x100058a38` 引用): - `InJa@jsax5y` (11B) 与 `tztXGiTqcK4ZwGaIdY_3sxk4nwvGN40o` (32B) - xref 上下文: `setAnimation` / `%d.jpg` / `%s/%s` — 是 spine/动画资源的**内部命名串**与格式串, XOR 0x10 解不出可读文本, 排除密钥属性。 --- ## 二、壳层 SDK / 平台侧凭据 (游戏 Lua 明文 + 盒子注入) 以下全部**已提取且在用** (来源: 解密后 AuthProxy.lua / DataRePort_launcher.lua / env.json): | 用途 | 值 | 状态 | |---|---|---| | 996SDK signkey (HMAC-SHA1) | `634eff98723b31da43ed35f0dd4edf36` | ✅ | | env.json signkey (渠道 110585) | `bb896500aac3d5b8394e7a0ce804171f` | ✅ | | sdkAppid / sdkAppkey | `ykOL4T4d6Oav` / `bd4f8e2996bcdc2acb917517aa81e070` | ✅ | | 创角上报 key | `zg1zn559tgh4enh25mz2hn2` | ✅ | | 支付场景 key | `7PZJImoeAE5Dnjb6pCYu8Ja5Buhb2urL` | ✅ | | 聚合支付 secret | `ptONCD6UxNbQRxYrvdVpFACgL1Ir53rjfUO0lOM2Did0ZxGEg2WB0WfhtsqTT2ee` | ✅ | | EnterGameClient appid | `GAjWNTqNpOVx` | ✅ (protocol_bot 在用) | | 极验 GT4 captchaId (Mac H5 / PC) | `c93bfe22...` / `26e753da...` | ✅ | | BOXAPP-SHA256 HMAC 密钥 | `BB0AAAC906FC4B7CADB116A213D46689` | ✅ (PC loginPreload.js 提取, 3 会话离线复算匹配) | ### 盒子登录 RSA 公钥 (会轮换, 已有自愈机制) - Mac 盒子二进制硬编码: `MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAjCQvqNPnOZm6GVDqeOb5S2pJ...` (RSA-1024) - 实验实证: 服务端会**轮换**公钥 (换钥时返回 20010); `传奇_bak/login_996pc.py` 已实现 "MySQL 公钥库 + 从 PC 登录页 webpack 模块 236 自动提取新公钥"的自愈。 - 状态: ✅ 机制+当前值均可提取, 且公钥本就是公开材料, 无"挖不出"问题。 --- ## 三、清点结论 | 类别 | 数量 | 遗漏 | |---|---|---| | 对称密钥 (XXTEA key/sign) | 主组×1 + 副组×1 + 备用×2 | **副组 `9V8N6QngLT`/`!yscqzip` 为本轮新增** (文档原缺) | | 非对称 (RSA) | 0 (stub 定论) + 平台公钥 1 (可轮换自愈) | 无 | | HMAC/签名 key | 7 组 (SDK/盒子/支付/上报) | 无 | | 动态凭据 (JWT/会话 key32/水印序列) | 运行时下发 | 设计如此, 非静态可挖 | **最终答案**: 除本轮新补的 XXTEA 渠道副组 (`9V8N6QngLT` / `!yscqzip`, 明文存于 0x6c60ba/0x6c60c5) 外, **没有其他未梳理出的静态密钥**。RSA 已有 stub 定论; 其余全部凭据均已在库且经实测验证。 --- ## 五、缺失/未找到密钥清单 (诚实记录, 2026-09-23 定性) 以下凭据**确属"客户端中没有、也挖不到"**, 但逐一核实过成因, 均不构成工程缺口: | # | 凭据 | 缺失原因 | 影响 | |---|---|---|---| | 1 | 游戏内 RSA 私钥/公钥 | 引擎模板预留接口, 实现为空壳 stub, 密钥从未编译进包 (rsa_investigation.md 证据链) | 无 — 服务器未启用该通道 | | 2 | 游戏服会话密钥 (SC529 key32) | 服务端每次登录动态下发, 客户端只回传不存储 | 无 — bot 已实现动态接收 (cq2_pure_enter.py) | | 3 | 反作弊水印 Sequence 值 | 按 `{NetStampHost}/{MD5(serverID)}.txt` + UnixTime 实时索引, 服务端下发 | 抓包/做 bot 时需按协议实时拉取 | | 4 | XTWebSocket_token (盒子 WebSocket 鉴权 JWT) | 运行时由服务端签发, 非静态; **WebSocket 用途至今未在协议链中定位** (盒子文档 §14.1 #11 遗留) | bot 链路未用, 待未来定位用途时再取 | | 5 | 支付回调验签密钥 (服务端↔服务端) | 双向验签密钥只存在于 996 服务端, 客户端仅持有上行签名 key (7PZJImoe... 已提取) | 无法伪造服务端回调 — 这本就是设计目标 | | 6 | Sparkle 更新源 appcast 签名 | 未在二进制发现 (疑运行时下发), 盒子文档 §13.12 遗留 | 与游戏协议无关 | | 7 | 极验 GT4 私有校验密钥 (cap_key) | 在极验云端, 客户端/前端只有 captchaId; 已实现滑块行为破解绕过 (GeekedTest) | 无 — 已绕过 | | 8 | Keychain 存储的密码/UUID | 运行时用户数据 (service: XYUUID-KeyChain-ServiceDomain), 非二进制常量 | 非逆向目标 | **定性总结**: 客户端静态可挖的密钥 = §一/§二清单, 已 100% 覆盖; "缺失"的 8 项全部属于**动态下发或只存服务端**两类, 属客观不可静态提取, 非梳理遗漏。 ## 六、复挖指南 (换渠道包时) 1. XXTEA: `strings` 定位 `SetXXTEAKeyGM` → r2 `aaa; axt` → 绑定函数 → 0x100043bdc 读字面量对; XOR 表字节 @`__DATA 0x1008ae5b0`; 注意**同时检查明文直传组** (0x6c60ba 附近 8B ldr 拼接)。 2. 验证: 用候选 key 对任意 `.lua` 去头后跑 XXTEA, 明文可读即命中 (本仓库 `cpp_reversed/xxtea.py` 可直接用)。 3. 平台侧: signkey/appkey 均在解密 Lua 内明文; RSA 公钥从 PC 登录页 chunk 提取 (见传奇_bak)。