| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- #!/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)
|