初中生
 
- 金币
- 349
- 好评
- 1
- 信誉
- 100
|
- """
- 通用加解密与 JWT 刷新模块
- 提供三个函数:
- - encrypt_request(payload) -> bytes
- - decrypt_response(encrypted_data) -> dict
- - refresh_jwt(old_token=None) -> str
- """
- import os
- import json
- import time
- import requests
- from Crypto.Cipher import AES
- from Crypto.Util.Padding import pad, unpad
- # ---------- 固定加密参数 ----------
- _AES_KEY = b"W98$9@F9@NlJ6oIwIylrjR2JP8JNa5wt" # 32 字节
- _AES_IV = b"iijbSYXWrsjQksaS" # 16 字节
- # ---------- 公共函数 ----------
- def encrypt_request(payload: dict) -> bytes:
- """
- 将明文字典请求体加密为二进制数据。
- 自动添加当前毫秒时间戳(若 payload 中未包含 timestamp)。
- """
- # 深拷贝避免修改原字典
- data = payload.copy()
- # 确保 common 存在且包含 timestamp
- if "common" in data:
- if "timestamp" not in data["common"]:
- data["common"]["timestamp"] = int(time.time() * 1000)
- else:
- # 若无 common,直接在顶层添加 timestamp(兼容非标准用法)
- if "timestamp" not in data:
- data["timestamp"] = int(time.time() * 1000)
- json_str = json.dumps(data, separators=(',', ':')) # 紧凑格式
- plaintext = json_str.encode('utf-8')
- cipher = AES.new(_AES_KEY, AES.MODE_CBC, _AES_IV)
- padded = pad(plaintext, AES.block_size)
- return cipher.encrypt(padded)
- def decrypt_response(encrypted_data: bytes) -> dict:
- """解密二进制响应体,返回明文字典。"""
- cipher = AES.new(_AES_KEY, AES.MODE_CBC, _AES_IV)
- decrypted = cipher.decrypt(encrypted_data)
- unpadded = unpad(decrypted, AES.block_size)
- json_str = unpadded.decode('utf-8')
- return json.loads(json_str)
- def refresh_jwt(old_token: str = None) -> str:
- """
- 使用旧 JWT 刷新,返回新 JWT 字符串。
- 若 old_token 为 None,则从环境变量 WIFIallinonekwy 读取。
- 自动去除 'Bearer ' 前缀。
- """
- if old_token is None:
- old_token = os.environ.get("WIFIallinonekwy")
- if not old_token:
- raise ValueError("未提供旧 JWT 且环境变量 WIFIallinonekwy 未设置或为空。")
- # 去除可能的 "Bearer " 前缀
- if old_token.startswith("Bearer "):
- old_token = old_token[7:]
- # ---------- 构造 refresh_token 请求体(固定字段) ----------
- refresh_payload = {
- "common": {
- "projectCode": "wifi",
- "appId": "TT0066",
- "verCode": "260723",
- "verName": "5.2.25",
- "channelId": "zb_oppo",
- "uid": "2e3f2899cf074d9ab26937d316771d99",
- "dhid": "bbga9ccf3h16v1a5881f6c2b4bcba077",
- "deviceId": "a2811bfd9eced1ef870b89d3b43000b7",
- "aid": "1c26f6fc799e1b85",
- "model": "PKG110",
- "manuf": "OnePlus",
- "osVerCode": "35",
- "sim_operator": "CTCC",
- "net": "4",
- "oaid": "47685F5B5DCB45938EAEC2F77D3D8C1149b1407c06d2ae9db56f153d2c40f8f1",
- "bootId": "482237067", # 此值可保持不变,或根据实际情况更新
- "sdkVersion": "1.3.7",
- "sdkVerCode": "37",
- "clientTaichis": "V1_LSKEY_158016_B,V1_LSKEY_159177_null,V1_LSKEY_161226_A,V1_LSKEY_162189_A,V1_LSKEY_162477_C,V1_LSKEY_164890_A,V1_LSKEY_163921_C,V1_LSKEY_165250_A,V1_LSKEY_167542_A",
- "platform": "android",
- "isMu": 0
- }
- }
- # 加密请求体
- encrypted_body = encrypt_request(refresh_payload)
- # 发送请求
- url = "https://coin-api.y5coin.com/coin/user/refresh_token"
- headers = {
- "Content-Type": "application/json",
- "Charset": "UTF-8",
- "Accept": "*/*",
- "x-project-code": "wifi",
- "x-sdk-version": "37",
- "x-platform": "android",
- "x-http-jwt-token": f"Bearer {old_token}",
- "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 15; PKG110 Build/UKQ1.231108.001)",
- "Connection": "Keep-Alive",
- "Accept-Encoding": "gzip",
- }
- resp = requests.post(url, headers=headers, data=encrypted_body)
- resp.raise_for_status()
- # 解密响应
- result = decrypt_response(resp.content)
- new_jwt = result.get("data", {}).get("newJwtToken")
- if not new_jwt:
- raise KeyError("响应中未找到 newJwtToken,请检查接口返回结构。")
- return new_jwt
- # ---------- 可选:直接运行测试 ----------
- if __name__ == "__main__":
- try:
- # 测试刷新 JWT(需要环境变量 WIFIallinonekwy)
- new_token = refresh_jwt()
- print("刷新成功,新 JWT:")
- print(new_token)
- print("\n--- 测试加密函数 ---")
- test_payload = {"common": {"foo": "bar"}}
- encrypted = encrypt_request(test_payload)
- print(f"加密长度: {len(encrypted)}")
- # 解密测试
- decrypted = decrypt_response(encrypted)
- print("解密结果:", decrypted)
- except Exception as e:
- print(f"测试错误: {e}")
复制代码 刷新jwt:旧jwttoken传入,传出新jwttoken
加密请求体:明文dict—> 二进制
解密请求体:二进制—>明文dict
|
|