#!/usr/bin/env python3 """ API Key 加解密测试脚本 测试三种场景: 1. Python 加密 → Python 解密 2. Python 加密 → JavaScript 解密(输出 JS 代码供浏览器控制台测试) 3. 多个不同长度的 key 测试 """ import os import sys # 设置测试密钥 os.environ['APIKEY_ENCRYPT_KEY'] = '25e9e87b18cf40d0ed0f102b8d2ec3a8' sys.path.insert(0, 'backend') from app.utils.apikey_crypto import encrypt_api_key, decrypt_api_key def test_python(): print("=" * 60) print("测试 1: Python 加密 → Python 解密") print("=" * 60) test_cases = [ "sk-1234567890abcdef", "sk-very-long-api-key-with-special-chars-!@#$%^&*()", "short", "中文测试密钥", "a" * 100, # 长 key ] all_ok = True for i, original in enumerate(test_cases, 1): try: encrypted = encrypt_api_key(original) decrypted = decrypt_api_key(encrypted) ok = original == decrypted all_ok = all_ok and ok print(f"\n[{i}] {'✓' if ok else '✗'}") print(f" 原文: {original[:50]}{'...' if len(original) > 50 else ''}") print(f" 密文: {encrypted[:60]}{'...' if len(encrypted) > 60 else ''}") print(f" 解密: {decrypted[:50]}{'...' if len(decrypted) > 50 else ''}") if not ok: print(f" ❌ 解密失败!") except Exception as e: print(f"\n[{i}] ✗ 异常: {e}") all_ok = False print(f"\n{'='*60}") print(f"Python 测试结果: {'全部通过 ✓' if all_ok else '有失败 ✗'}") print(f"{'='*60}\n") return all_ok def test_javascript(): print("=" * 60) print("测试 2: JavaScript 解密验证") print("=" * 60) test_key = "sk-test-key-for-javascript-1234567890" encrypted = encrypt_api_key(test_key) secret = os.environ['APIKEY_ENCRYPT_KEY'] print(f"\n原文: {test_key}") print(f"密文: {encrypted}") print(f"密钥: {secret}") print("\n复制以下 JavaScript 代码到浏览器控制台运行:") print("-" * 60) js_code = f""" // ── 解密函数 ────────────────────────────────────────────────────────────────── async function deriveKeystream(key, length) {{ const enc = new TextEncoder(); const keyBytes = enc.encode(key); const stream = []; let block = 0; while (stream.length < length) {{ const blockBytes = new Uint8Array(4); new DataView(blockBytes.buffer).setUint32(0, block, false); const input = new Uint8Array([...keyBytes, ...blockBytes]); const hash = await crypto.subtle.digest('SHA-256', input); stream.push(...new Uint8Array(hash)); block++; }} return stream.slice(0, length); }} function rotr8(byte, n) {{ n = n % 8; return ((byte >>> n) | (byte << (8 - n))) & 0xFF; }} function base64urlDecode(str) {{ str = str.replace(/-/g, '+').replace(/_/g, '/'); while (str.length % 4) str += '='; return Uint8Array.from(atob(str), c => c.charCodeAt(0)); }} async function decryptApiKey(ciphertext, secretKey) {{ const data = base64urlDecode(ciphertext); const keystream = await deriveKeystream(secretKey, data.length); const result = new Uint8Array(data.length); for (let i = 0; i < data.length; i++) {{ const unshifted = rotr8(data[i], i % 5 + 1); result[i] = unshifted ^ keystream[i]; }} return new TextDecoder().decode(result); }} // ── 测试数据 ────────────────────────────────────────────────────────────────── const encrypted = "{encrypted}"; const secretKey = "{secret}"; const expected = "{test_key}"; // ── 执行解密 ────────────────────────────────────────────────────────────────── decryptApiKey(encrypted, secretKey).then(decrypted => {{ console.log('原文:', expected); console.log('密文:', encrypted); console.log('解密:', decrypted); console.log('验证:', decrypted === expected ? '✓ 通过' : '✗ 失败'); }}); """ print(js_code) print("-" * 60) print("\n预期输出: 解密结果应该等于原文") print(f"{'='*60}\n") def test_edge_cases(): print("=" * 60) print("测试 3: 边界情况") print("=" * 60) cases = [ ("空字符串", ""), ("单字符", "a"), ("特殊符号", "!@#$%^&*()_+-=[]{{}}|;':\",./<>?"), ("Emoji", "🔑🚀💻"), ] all_ok = True for name, original in cases: if not original: # 空字符串跳过 print(f"\n[{name}] 跳过(空字符串)") continue try: encrypted = encrypt_api_key(original) decrypted = decrypt_api_key(encrypted) ok = original == decrypted all_ok = all_ok and ok print(f"\n[{name}] {'✓' if ok else '✗'}") print(f" 原文: {original}") print(f" 密文: {encrypted}") print(f" 解密: {decrypted}") except Exception as e: print(f"\n[{name}] ✗ 异常: {e}") all_ok = False print(f"\n{'='*60}") print(f"边界测试结果: {'全部通过 ✓' if all_ok else '有失败 ✗'}") print(f"{'='*60}\n") return all_ok if __name__ == "__main__": print("\n🔐 API Key 加解密测试\n") r1 = test_python() test_javascript() r2 = test_edge_cases() print("=" * 60) print("总结") print("=" * 60) print(f"Python 加解密: {'✓ 通过' if r1 else '✗ 失败'}") print(f"边界情况: {'✓ 通过' if r2 else '✗ 失败'}") print(f"\n最终结果: {'🎉 全部通过' if r1 and r2 else '❌ 有失败'}") print("=" * 60) sys.exit(0 if r1 and r2 else 1)