""" Cookie Cloud 客户端(独立前端使用) """ import json import hashlib import logging import requests from base64 import b64decode logger = logging.getLogger('cookie_cloud') try: from Cryptodome.Cipher import AES from Cryptodome.Util.Padding import unpad except ImportError: from Crypto.Cipher import AES from Crypto.Util.Padding import unpad def cookie_decrypt(uuid: str, encrypted_b64: str, password: str) -> dict: """解密Cookie Cloud数据""" the_key = hashlib.md5(f"{uuid}-{password}".encode()).hexdigest()[:16].encode() encrypted_data = b64decode(encrypted_b64) logger.info("尝试AES-ECB解密...") try: cipher = AES.new(the_key, AES.MODE_ECB) decrypted = cipher.decrypt(encrypted_data) result = unpad(decrypted, AES.block_size) data = json.loads(result.decode('utf-8')) logger.info("AES-ECB解密成功") return data except Exception as e: logger.info(f"AES-ECB解密失败: {e},尝试Salted__格式...") pass if encrypted_data[:8] == b'Salted__': logger.info("检测到Salted__格式,尝试CBC解密...") salt = encrypted_data[8:16] ciphertext = encrypted_data[16:] logger.info(f"Salt: {salt.hex()}") d = [b''] while len(b''.join(d)) < 48: d.append(hashlib.md5(d[-1] + the_key + salt).digest()) key_iv = b''.join(d) cipher = AES.new(key_iv[:32], AES.MODE_CBC, key_iv[32:48]) decrypted = unpad(cipher.decrypt(ciphertext), AES.block_size) data = json.loads(decrypted.decode('utf-8')) logger.info("CBC解密成功") return data logger.error("所有解密方式均失败") raise ValueError('无法解密Cookie数据') def download_cookies(api_url: str, uuid: str, password: str) -> dict: """从Cookie Cloud服务器下载并解密Cookie""" api_url = api_url.rstrip('/') url = f"{api_url}/get/{uuid}" logger.info(f"[1/3] 请求Cookie Cloud: {url}") logger.info(f"[1/3] UUID: {uuid}") response = requests.get(url, params={'password': password}, timeout=10) response.raise_for_status() result = response.json() logger.info(f"[1/3] HTTP状态码: {response.status_code}") logger.info(f"[1/3] 返回数据keys: {list(result.keys())}") logger.info(f"[1/3] 返回数据大小: {len(json.dumps(result))} bytes") if isinstance(result, dict) and result.get('encrypted'): logger.info("[2/3] 检测到加密数据,开始解密...") result = cookie_decrypt(uuid, result['encrypted'], password) logger.info(f"[2/3] 解密完成,数据类型: {type(result)}") if isinstance(result, dict): logger.info(f"[2/3] Cookie数据包含域名: {list(result.keys())}") if isinstance(result, dict) and 'cookie_data' in result: cookies_data = result.get('cookie_data', {}) logger.info(f"[3/3] 新版CookieCloud格式,提取cookie_data") logger.info(f"[3/3] cookie_data包含域名数: {len(cookies_data)}") return cookies_data logger.info(f"[3/3] 返回数据已处理完成") return result def get_cookies_for_domain(cookies_data: dict, domain: str) -> list: """提取指定域名对应的Cookie列表""" result = [] matched_hosts = [] domain_parts = domain.lower().split('.') for host, cookie_list in cookies_data.items(): host_clean = host.lower().lstrip('.') domain_clean = domain.lower() is_match = False if host_clean == domain_clean: is_match = True elif host_clean.endswith('.' + domain_clean): is_match = True elif domain_clean.endswith('.' + host_clean): is_match = True if is_match: matched_hosts.append(host) if isinstance(cookie_list, list): for cookie in cookie_list: if cookie.get('name') and cookie.get('value'): result.append({ 'name': cookie['name'], 'value': cookie['value'], 'domain': cookie.get('domain', domain), 'path': cookie.get('path', '/') }) logger.info(f"域名匹配结果: 目标={domain}, 匹配hosts={matched_hosts}") logger.info(f"提取Cookie数量: {len(result)}") if result: cookie_names = [c['name'] for c in result[:5]] logger.info(f"前5个Cookie名称: {cookie_names}") return result