165 lines
6.0 KiB
Python
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
|