移除二维码信封历史数据依赖

This commit is contained in:
yml2213
2026-08-31 17:43:55 +08:00
parent 05b1325a04
commit d391e2ce3e
6 changed files with 546 additions and 937 deletions
+21 -19
View File
@@ -9,7 +9,8 @@
6. POST /web/cookie/verify 兑换获取全套网页 Cookie
注册链不再重放旧 dfpReport 密文。登录帧的 32hex hdid 仍是服务端硬锚,
当前继续使用已注册样本;新注册链动态更新的是 safedeviceid 和 device_id。
登录帧中的 HDID32 是 app 版本级协议常量;二维码信封的 ACTION、设备字段、
UID、证书和会话元数据均在本次登录中动态生成或由注册链签发。
注册链(``core/huya/dfp_register``)每次登录前执行,失败即抛错终止(``HuyaAppLoginError``),
不读取画像里的旧固定值,也不静默回退旧链。
@@ -35,7 +36,7 @@ from urllib.parse import parse_qs, quote, urlparse
import requests
from loguru import logger
from .cert_forge import build_p1, decrypt_cert, forge_cert, parse_p1
from .cert_forge import build_p1, forge_cert
from .cookie_utils import normalize_huya_cookie
from .device_fingerprint import account_state_dir, get_huya_sdid, reset_account_state
from .device_profile import get_profile, mobile_user_agent
@@ -270,7 +271,8 @@ def login_cred_with_flow(
max_rounds: int = 3,
device_info: dict | None = None,
proxies: dict | None = None,
) -> tuple[bytes, int]:
include_device_token: bool = False,
) -> tuple[bytes, int] | tuple[bytes, int, str]:
"""新注册设备后登录,返回 ``(新鲜 cred, 真实 uid)``。
注册只执行一次;safe_auth 通过后的重发继续使用同一组设备字段。
@@ -305,6 +307,8 @@ def login_cred_with_flow(
)
if cred:
uid = parse_real_uid(resp)
if include_device_token:
return cred, uid, safedeviceid
return cred, uid
if risk_url:
kind = (
@@ -462,11 +466,12 @@ class HuyaAppPasswordLogin:
# 1) 获取新鲜 cred 与 真实 uid (自动过 safe_auth 滑块)
try:
cred, uid = login_cred_with_flow(
cred, uid, safedeviceid = login_cred_with_flow(
acct,
self.password,
device_info=self.device_info,
proxies=self.proxies,
include_device_token=True,
)
except HuyaAppQrAuthRequiredError as exc:
return HuyaLoginResult(
@@ -485,30 +490,27 @@ class HuyaAppPasswordLogin:
# 2) 本地生成 nonce 铸造证书 (P1 指纹与该账号设备画像一致)
try:
env = Envelope.load()
orig = base64.b64decode(env.cert_b64)
f = parse_p1(decrypt_cert(orig))
st = int(time.time() * 1000)
rnd = gen_nonce(uid, K1_DEFAULT, service_time_ms=st, counter=0)
fp_bytes = self.device_info["fingerprint"].encode("ascii")
p1 = build_p1(f["app_id"], fp_bytes, cred, rnd=rnd)
cert = base64.b64encode(forge_cert(p1, key_idx=orig[1])).decode()
p1 = build_p1(b"5008", fp_bytes, cred, rnd=rnd)
# 证书头和 app_id 是协议版本常量,不从抓包信封读取。
cert = base64.b64encode(forge_cert(p1, key_idx=0x20)).decode()
# 3) 信封补丁
raw = bytearray(env.raw)
if env.cert_off is None or env.uid_off is None:
raise ValueError("信封缺少证书或 uid 偏移")
raw[env.cert_off : env.cert_off + env.cert_len] = cert.encode("ascii")
if env.uid != uid:
struct.pack_into(">Q", raw, env.uid_off, uid)
# QR 信封只保留协议结构;不要重放抓包里的旧会话值。
# 3) 按当前账号画像和本次注册令牌重编码二维码信封。
qr_session = random.randint(1_000_000, 9_999_999)
qr_trace = (
f"{uuid.uuid4().hex[:16]}-{random.randint(10000, 99999)}-"
f"{time.time_ns():020d}"
)
env.raw = raw
env.patch_session(qr_session).patch_meta(qr_session, qr_trace)
env = Envelope.build_qr(
uid=uid,
cert_b64=cert,
safedeviceid=safedeviceid,
session=qr_session,
trace_id=qr_trace,
device_info=self.device_info,
)
wup = base64.b64encode(bytes(env.raw)).decode("ascii")
except Exception as exc: # noqa: BLE001 外部接口与任务边界需要保留宽泛异常兜底
return HuyaLoginResult(