Files
kami_itunes_third_api/src/utils/test_crypto.py
danial 584a258c50 feat(utils): 新增非对称加密RSA工具与示例
- 实现RSA密钥对的生成、导出、加载功能
- 新增RSA公钥加密与私钥解密接口,支持Base64和Hex编码
- 实现RSA私钥数字签名及公钥签名验证功能
- 添加RSA密钥对文件读写辅助函数
- 新增非对称加密使用示例,涵盖密钥生成、加解密、签名验证等场景
- 提供项目中集成非对称加密的应用示例,包括安全API请求、数据加密、证书签发与认证令牌
- 添加完善的单元测试覆盖密钥管理、加密解密、签名验证及边界情况
- 调整依赖版本,替换pycryptodome为cryptography包
- 优化部分已有加密代码,改用cryptography库实现AES加密,增强兼容性和安全性
2025-11-12 13:46:06 +08:00

201 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
非对称加密辅助函数单元测试
"""
import unittest
from src.utils.crypto import (
RSAKeyPair,
encrypt_with_rsa,
decrypt_with_rsa,
sign_with_rsa,
verify_rsa_signature,
)
class TestRSAKeyPair(unittest.TestCase):
"""测试 RSAKeyPair 类"""
def setUp(self):
"""测试前准备"""
self.key_pair = RSAKeyPair.generate(key_size=2048)
def test_generate_keys(self):
"""测试生成密钥对"""
self.assertIsNotNone(self.key_pair.private_key)
self.assertIsNotNone(self.key_pair.public_key)
def test_get_private_key_pem(self):
"""测试获取 PEM 格式私钥"""
private_pem = self.key_pair.get_private_key_pem()
self.assertIn("-----BEGIN PRIVATE KEY-----", private_pem)
self.assertIn("-----END PRIVATE KEY-----", private_pem)
def test_get_public_key_pem(self):
"""测试获取 PEM 格式公钥"""
public_pem = self.key_pair.get_public_key_pem()
self.assertIn("-----BEGIN PUBLIC KEY-----", public_pem)
self.assertIn("-----END PUBLIC KEY-----", public_pem)
def test_load_private_key_from_pem(self):
"""测试从 PEM 字符串加载私钥"""
private_pem = self.key_pair.get_private_key_pem()
loaded_key_pair = RSAKeyPair.load_private_key_from_pem(private_pem)
self.assertIsNotNone(loaded_key_pair.private_key)
self.assertIsNotNone(loaded_key_pair.public_key)
def test_load_public_key_from_pem(self):
"""测试从 PEM 字符串加载公钥"""
public_pem = self.key_pair.get_public_key_pem()
loaded_key_pair = RSAKeyPair.load_public_key_from_pem(public_pem)
self.assertIsNone(loaded_key_pair.private_key)
self.assertIsNotNone(loaded_key_pair.public_key)
class TestRSAEncryption(unittest.TestCase):
"""测试 RSA 加密和解密"""
def setUp(self):
"""测试前准备"""
self.key_pair = RSAKeyPair.generate(key_size=2048)
self.private_pem = self.key_pair.get_private_key_pem()
self.public_pem = self.key_pair.get_public_key_pem()
self.plaintext = "Hello, World!"
def test_encrypt_decrypt_base64(self):
"""测试使用 Base64 编码的加密和解密"""
ciphertext = encrypt_with_rsa(
self.plaintext, self.public_pem, encoding="base64"
)
decrypted = decrypt_with_rsa(ciphertext, self.private_pem, encoding="base64")
self.assertEqual(self.plaintext, decrypted)
self.assertNotEqual(self.plaintext, ciphertext)
def test_encrypt_decrypt_hex(self):
"""测试使用 Hex 编码的加密和解密"""
ciphertext = encrypt_with_rsa(self.plaintext, self.public_pem, encoding="hex")
decrypted = decrypt_with_rsa(ciphertext, self.private_pem, encoding="hex")
self.assertEqual(self.plaintext, decrypted)
self.assertNotEqual(self.plaintext, ciphertext)
def test_encrypt_unicode(self):
"""测试加密 Unicode 文本"""
unicode_text = "你好,世界!🔐"
ciphertext = encrypt_with_rsa(unicode_text, self.public_pem)
decrypted = decrypt_with_rsa(ciphertext, self.private_pem)
self.assertEqual(unicode_text, decrypted)
def test_encrypt_with_invalid_encoding(self):
"""测试使用无效编码方式加密"""
with self.assertRaises(ValueError):
encrypt_with_rsa(self.plaintext, self.public_pem, encoding="invalid")
def test_decrypt_with_invalid_encoding(self):
"""测试使用无效编码方式解密"""
ciphertext = encrypt_with_rsa(
self.plaintext, self.public_pem, encoding="base64"
)
with self.assertRaises(ValueError):
decrypt_with_rsa(ciphertext, self.private_pem, encoding="invalid")
class TestRSASignature(unittest.TestCase):
"""测试 RSA 数字签名"""
def setUp(self):
"""测试前准备"""
self.key_pair = RSAKeyPair.generate(key_size=2048)
self.private_pem = self.key_pair.get_private_key_pem()
self.public_pem = self.key_pair.get_public_key_pem()
self.message = "This is a message to sign"
def test_sign_verify_base64(self):
"""测试使用 Base64 编码的签名和验证"""
signature = sign_with_rsa(self.message, self.private_pem, encoding="base64")
is_valid = verify_rsa_signature(
self.message, signature, self.public_pem, encoding="base64"
)
self.assertTrue(is_valid)
def test_sign_verify_hex(self):
"""测试使用 Hex 编码的签名和验证"""
signature = sign_with_rsa(self.message, self.private_pem, encoding="hex")
is_valid = verify_rsa_signature(
self.message, signature, self.public_pem, encoding="hex"
)
self.assertTrue(is_valid)
def test_verify_invalid_signature(self):
"""测试验证无效签名"""
signature = sign_with_rsa(self.message, self.private_pem)
# 修改消息
tampered_message = "This is a tampered message"
is_valid = verify_rsa_signature(
tampered_message, signature, self.public_pem, encoding="base64"
)
self.assertFalse(is_valid)
def test_verify_corrupted_signature(self):
"""测试验证损坏的签名"""
signature = sign_with_rsa(self.message, self.private_pem)
# 修改签名
corrupted_signature = signature[:-10] + "corrupted"
is_valid = verify_rsa_signature(
self.message, corrupted_signature, self.public_pem, encoding="base64"
)
self.assertFalse(is_valid)
def test_sign_unicode_message(self):
"""测试签名 Unicode 消息"""
unicode_message = "签名测试消息 🔐"
signature = sign_with_rsa(unicode_message, self.private_pem)
is_valid = verify_rsa_signature(unicode_message, signature, self.public_pem)
self.assertTrue(is_valid)
class TestEdgeCases(unittest.TestCase):
"""测试边界情况"""
def setUp(self):
"""测试前准备"""
self.key_pair = RSAKeyPair.generate(key_size=2048)
self.private_pem = self.key_pair.get_private_key_pem()
self.public_pem = self.key_pair.get_public_key_pem()
def test_encrypt_empty_string(self):
"""测试加密空字符串"""
plaintext = ""
ciphertext = encrypt_with_rsa(plaintext, self.public_pem)
decrypted = decrypt_with_rsa(ciphertext, self.private_pem)
self.assertEqual(plaintext, decrypted)
def test_encrypt_long_message(self):
"""测试加密长消息应该失败RSA 有长度限制)"""
# RSA 2048 位密钥最多能加密约 190 字节
long_plaintext = "A" * 300
with self.assertRaises(Exception):
encrypt_with_rsa(long_plaintext, self.public_pem)
def test_sign_empty_message(self):
"""测试对空消息签名"""
message = ""
signature = sign_with_rsa(message, self.private_pem)
is_valid = verify_rsa_signature(message, signature, self.public_pem)
self.assertTrue(is_valid)
if __name__ == "__main__":
unittest.main()