mirror of
https://git.oceanpay.cc/danial/kami_itunes_third_api.git
synced 2025-12-18 22:20:08 +00:00
- 实现RSA密钥对的生成、导出、加载功能 - 新增RSA公钥加密与私钥解密接口,支持Base64和Hex编码 - 实现RSA私钥数字签名及公钥签名验证功能 - 添加RSA密钥对文件读写辅助函数 - 新增非对称加密使用示例,涵盖密钥生成、加解密、签名验证等场景 - 提供项目中集成非对称加密的应用示例,包括安全API请求、数据加密、证书签发与认证令牌 - 添加完善的单元测试覆盖密钥管理、加密解密、签名验证及边界情况 - 调整依赖版本,替换pycryptodome为cryptography包 - 优化部分已有加密代码,改用cryptography库实现AES加密,增强兼容性和安全性
201 lines
7.0 KiB
Python
201 lines
7.0 KiB
Python
"""
|
||
非对称加密辅助函数单元测试
|
||
"""
|
||
|
||
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()
|