geo/backend/tests/test_services/test_key_encryption.py

165 lines
6.0 KiB
Python

import pytest
from cryptography.fernet import Fernet
class TestKeyEncryptionBasic:
"""基础加密解密测试"""
def test_encrypt_decrypt_roundtrip(self):
from app.services.key_encryption import KeyEncryption
encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345")
plaintext = "sk-1234567890abcdef"
ciphertext = encryption.encrypt(plaintext)
decrypted = encryption.decrypt(ciphertext)
assert decrypted == plaintext
def test_encrypted_content_differs_from_plaintext(self):
from app.services.key_encryption import KeyEncryption
encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345")
plaintext = "sk-1234567890abcdef"
ciphertext = encryption.encrypt(plaintext)
assert ciphertext != plaintext
assert ciphertext != plaintext.encode()
def test_same_plaintext_produces_different_ciphertext(self):
from app.services.key_encryption import KeyEncryption
encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345")
plaintext = "sk-1234567890abcdef"
ciphertext1 = encryption.encrypt(plaintext)
ciphertext2 = encryption.encrypt(plaintext)
assert ciphertext1 != ciphertext2
class TestKeyEncryptionEdgeCases:
"""边界情况测试"""
def test_encrypt_empty_string_raises_error(self):
from app.services.key_encryption import KeyEncryption
encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345")
with pytest.raises(ValueError, match="Cannot encrypt empty string"):
encryption.encrypt("")
def test_decrypt_empty_string_raises_error(self):
from app.services.key_encryption import KeyEncryption
encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345")
with pytest.raises(ValueError, match="Cannot decrypt empty string"):
encryption.decrypt("")
def test_encrypt_special_characters(self):
from app.services.key_encryption import KeyEncryption
encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345")
plaintext = "sk-中文测试!@#$%^&*()_+-=[]{}|;':\",./<>?"
ciphertext = encryption.encrypt(plaintext)
decrypted = encryption.decrypt(ciphertext)
assert decrypted == plaintext
def test_encrypt_unicode_characters(self):
from app.services.key_encryption import KeyEncryption
encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345")
plaintext = "sk-日本語テスト한국어"
ciphertext = encryption.encrypt(plaintext)
decrypted = encryption.decrypt(ciphertext)
assert decrypted == plaintext
class TestKeyEncryptionInvalidInputs:
"""无效输入测试"""
def test_decrypt_invalid_ciphertext_raises_error(self):
from app.services.key_encryption import KeyEncryption
encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345")
with pytest.raises(ValueError, match="Invalid ciphertext or key"):
encryption.decrypt("invalid-ciphertext-that-cannot-be-decrypted")
def test_decrypt_with_wrong_key_raises_error(self):
from app.services.key_encryption import KeyEncryption
encryption1 = KeyEncryption(encryption_key="key-one-for-encryption-1234")
encryption2 = KeyEncryption(encryption_key="key-two-for-encryption-1234")
plaintext = "sk-1234567890abcdef"
ciphertext = encryption1.encrypt(plaintext)
with pytest.raises(ValueError, match="Invalid ciphertext or key"):
encryption2.decrypt(ciphertext)
class TestKeyEncryptionKeyFormats:
"""密钥格式测试"""
def test_valid_fernet_key_format(self):
from app.services.key_encryption import KeyEncryption
valid_key = Fernet.generate_key().decode()
encryption = KeyEncryption(encryption_key=valid_key)
plaintext = "sk-1234567890abcdef"
ciphertext = encryption.encrypt(plaintext)
decrypted = encryption.decrypt(ciphertext)
assert decrypted == plaintext
def test_password_based_key_derivation(self):
from app.services.key_encryption import KeyEncryption
password = "my-secret-password-12345"
encryption = KeyEncryption(encryption_key=password)
plaintext = "sk-1234567890abcdef"
ciphertext = encryption.encrypt(plaintext)
decrypted = encryption.decrypt(ciphertext)
assert decrypted == plaintext
class TestKeyEncryptionSingleton:
"""全局实例测试"""
def test_get_key_encryption_returns_instance(self):
from app.services.key_encryption import get_key_encryption
instance = get_key_encryption()
assert instance is not None
assert hasattr(instance, "encrypt")
assert hasattr(instance, "decrypt")
def test_reset_key_encryption_clears_singleton(self):
from app.services.key_encryption import get_key_encryption, reset_key_encryption
instance1 = get_key_encryption()
reset_key_encryption()
instance2 = get_key_encryption()
assert instance1 is not instance2
class TestAPIKeyManagerEncryption:
"""APIKeyManager集成测试"""
def test_api_key_manager_uses_fernet_encryption(self):
from app.services.api_key_manager import APIKeyManager
manager = APIKeyManager()
original_key = "sk-1234567890abcdef"
config = manager.add_key("chatgpt", original_key)
assert config.encrypted_key != original_key
assert not config.encrypted_key.startswith("sk-")
decrypted = manager.get_key("chatgpt")
assert decrypted == original_key
def test_encrypted_key_is_not_base64_of_plaintext(self):
from app.services.api_key_manager import APIKeyManager
import base64
manager = APIKeyManager()
original_key = "sk-1234567890abcdef"
config = manager.add_key("chatgpt", original_key)
plain_base64 = base64.b64encode(original_key.encode()).decode()
assert config.encrypted_key != plain_base64