feat(huya): 零设备 dfpReport 注册链迁入 core/huya 并接入生产登录
- 新增 core/huya/dfp_register: 随机 4146B cw 生成 + 注册响应解析 (t1/t2/t5), 修复 JSON 模板 %s 数不匹配的 TypeError bug - app_login 每次 WUP 登录前执行注册链取新 safedeviceid/device_id, 不再读取画像旧固定值; 注册失败抛 HuyaAppLoginError 终止, 不静默回退旧链 - device_profile 移除固定 SAFEDEVICEID_DEFAULT, 画像只承载 soft 字段 - tools/huya_device_register 同步零设备生成链路 (--gen/--gen-login) - 新增 tests/test_huya_dfp_register (9 项), 扩展 test_huya_app_login 注册接线 (4 项)
This commit is contained in:
+51
-16
@@ -1,11 +1,17 @@
|
||||
"""虎牙 App 渠道协议登录模块。
|
||||
|
||||
流程:
|
||||
1. 账号+密码 -> 独立设备画像 -> WUP 密码登录 (POST wup.huya.com)
|
||||
2. safe_auth 滑块自动过验 -> 提取 fresh cred 与 真实 uid
|
||||
3. 本地 XXTEA 算 nonce -> 铸造登录证书 (cert_forge) -> 补丁 WUP 信封 (envelope_forge)
|
||||
4. 模拟扫码绑定四步流 (getQrId -> scanQrPicNotify -> bindQrLoginUser -> tryQrLogin) 获取 biztoken
|
||||
5. POST /web/cookie/verify 兑换获取全套网页 Cookie
|
||||
1. 零设备注册链生成随机 dfpReport,获取新 safedeviceid/device_id
|
||||
2. 账号+密码+新注册字段 -> WUP 密码登录 (POST wup.huya.com)
|
||||
3. safe_auth 滑块自动过验 -> 提取 fresh cred 与真实 uid
|
||||
4. 本地 XXTEA 算 nonce -> 铸造登录证书 (cert_forge) -> 补丁 WUP 信封 (envelope_forge)
|
||||
5. 模拟扫码绑定四步流 (getQrId -> scanQrPicNotify -> bindQrLoginUser -> tryQrLogin) 获取 biztoken
|
||||
6. POST /web/cookie/verify 兑换获取全套网页 Cookie
|
||||
|
||||
注册链不再重放旧 dfpReport 密文。登录帧的 32hex hdid 仍是服务端硬锚,
|
||||
当前继续使用已注册样本;新注册链动态更新的是 safedeviceid 和 device_id。
|
||||
注册链(``core/huya/dfp_register``)每次登录前执行,失败即抛错终止(``HuyaAppLoginError``),
|
||||
不读取画像里的旧固定值,也不静默回退旧链。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -27,6 +33,7 @@ from .cert_forge import build_p1, decrypt_cert, forge_cert, parse_p1
|
||||
from .cookie_utils import normalize_huya_cookie
|
||||
from .device_fingerprint import get_huya_sdid
|
||||
from .device_profile import get_profile
|
||||
from .dfp_register import DfpRegistrationError, register_device
|
||||
from .envelope_forge import Envelope
|
||||
from .login import HuyaCredentialError, HuyaLoginError, HuyaLoginResult
|
||||
from .nonce_forge import K1_DEFAULT, gen_nonce
|
||||
@@ -66,11 +73,6 @@ DEFAULT_GOLDEN_DEV = {
|
||||
"height": "2120",
|
||||
"device_id": "7c5387e0539c023c31c4ff0e807e7256117385ee",
|
||||
"hdid": "ed0db8334cadd236c00cadf7e11ab5a5",
|
||||
"safedeviceid": (
|
||||
"PQwemAN9NHkZKoMqVTFUZBIypqMTaQEOrmXr37xQVhQZqrL/gUKEQ11xvE0ju48V8O/"
|
||||
"t9UBGSp27m4+6bP4IiAEnpaR5Rj1kHEfN2SPLPqYZW9vroxUSoAvjJn6ezTP9jWGxxlRDCbt"
|
||||
"Py4Rd6MencYT/pNImVIWK+YbNKZt1O05bHUFhqHf3"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@@ -118,14 +120,29 @@ def wup_password_login_raw(
|
||||
hdid: str | None = None,
|
||||
proxies: dict | None = None,
|
||||
) -> bytes:
|
||||
"""发送 WUP 密码登录,返回原始响应字节。"""
|
||||
"""发送 WUP 密码登录,返回原始响应字节。
|
||||
|
||||
未显式传入 ``safedeviceid`` 时会先执行新设备注册链,不再回退旧的
|
||||
固定 action/device_id。风控重试调用方应显式复用同一注册结果。
|
||||
注册链失败抛 ``HuyaAppLoginError``,绝不静默回退旧固定值。
|
||||
"""
|
||||
uid_str = account[3:] if account.startswith("hy_") else account
|
||||
mj, ua, sd = _golden_session_assets()
|
||||
dev = device_info or DEFAULT_GOLDEN_DEV
|
||||
mj, ua, _old_sd = _golden_session_assets()
|
||||
dev = dict(device_info or DEFAULT_GOLDEN_DEV)
|
||||
if not safedeviceid:
|
||||
try:
|
||||
_t1, safedeviceid, registered_device_id = register_device(
|
||||
fingerprint=dev.get("fingerprint"),
|
||||
proxies=proxies,
|
||||
timeout=timeout,
|
||||
)
|
||||
except DfpRegistrationError as exc:
|
||||
raise HuyaAppLoginError(f"新设备注册失败: {exc}") from exc
|
||||
dev["device_id"] = registered_device_id
|
||||
pkt = build_password_login_wup(
|
||||
uid_str,
|
||||
hashlib.sha1(password.encode()).hexdigest(),
|
||||
safedeviceid or dev.get("safedeviceid") or sd,
|
||||
safedeviceid,
|
||||
hdid or dev.get("hdid") or "ed0db8334cadd236c00cadf7e11ab5a5",
|
||||
mj["session"],
|
||||
mj["traceId"],
|
||||
@@ -238,9 +255,27 @@ def login_cred_with_flow(
|
||||
device_info: dict | None = None,
|
||||
proxies: dict | None = None,
|
||||
) -> tuple[bytes, int]:
|
||||
"""账号密码 -> (新鲜cred, 真实uid)。自动过 safe_auth 滑块。"""
|
||||
"""新注册设备后登录,返回 ``(新鲜 cred, 真实 uid)``。
|
||||
|
||||
注册只执行一次;safe_auth 通过后的重发继续使用同一组设备字段。
|
||||
"""
|
||||
dev = dict(device_info or DEFAULT_GOLDEN_DEV)
|
||||
try:
|
||||
_t1, safedeviceid, registered_device_id = register_device(
|
||||
fingerprint=dev.get("fingerprint"),
|
||||
proxies=proxies,
|
||||
)
|
||||
except DfpRegistrationError as exc:
|
||||
raise HuyaAppLoginError(f"新设备注册失败: {exc}") from exc
|
||||
dev["device_id"] = registered_device_id
|
||||
for rnd in range(max_rounds):
|
||||
resp = wup_password_login_raw(account, password, device_info=device_info, proxies=proxies)
|
||||
resp = wup_password_login_raw(
|
||||
account,
|
||||
password,
|
||||
device_info=dev,
|
||||
safedeviceid=safedeviceid,
|
||||
proxies=proxies,
|
||||
)
|
||||
cred = parse_cred(resp)
|
||||
if cred:
|
||||
uid = parse_real_uid(resp)
|
||||
|
||||
Reference in New Issue
Block a user