import base64
import json
import random
from rich import print
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import hashlib
import requests
from requests.packages import urllib3
urllib3.disable_warnings()
ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
DEFAULT_HEADERS = {
"Host": "api4.magicalapp.cn",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip",
"Content-Type": "application/x-www-form-urlencoded"
}
def decrypt_string(encrypted_str: str) -> dict:
"""解密服务端返回的加密字符串"""
if len(encrypted_str) <= 16:
raise ValueError("Invalid encrypted string length")
key = encrypted_str[:16]
crypt_str = encrypted_str[16:]
try:
key_bytes = key.encode('utf-8')
crypt_bytes = base64.b64decode(crypt_str)
cipher = AES.new(key_bytes, AES.MODE_ECB)
decrypted = unpad(cipher.decrypt(crypt_bytes), AES.block_size)
return json.loads(decrypted.decode('utf-8'))
except Exception as e:
print(f"[解密数据时出错,请联系管理员处理] {str(e)}")
raise
def generate_random_string(length: int) -> str:
"""生成指定长度的随机字符串"""
return "".join(random.choices(ALPHABET, k=length))
def request(method: str, endpoint: str, **kwargs):
"""统一请求方法"""
_session = requests.Session()
_session.headers.update({
"User-Agent": "okhttp/4.9.3",
**DEFAULT_HEADERS
})
url = f"https://api4.magicalapp.cn/api{endpoint}"
response = _session.request(method, url, verify=False, **kwargs)
response.raise_for_status()
try:
data = response.json()
if isinstance(data, str):
return decrypt_string(data)
return data
except json.JSONDecodeError:
print(f"Invalid JSON response: {response.text}")
raise
def login(username: str, password: str):
"""用户登录"""
hashed_pwd = hashlib.md5(password.encode()).hexdigest()
data = {
"password": hashed_pwd,
"ip": "127.0.0.1",
"device": generate_random_string(32),
"email": username
}
try:
response = request("POST", "/user/login", data=data)
if response.get("code") != "200":
raise ValueError(response.get("msg", "Unknown error"))
user_data = response["data"]["user"]
print("Id:", user_data["id"])
print("Username:", user_data["userName"])
print("Token:", response["data"]["token"])
except requests.RequestException as e:
print(f"Login failed: {str(e)}")
raise
login(input("Username:"), input("Password:"))