asymmetric_encryption.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. from cryptography.hazmat.primitives import serialization, hashes
  2. from cryptography.hazmat.primitives.asymmetric import rsa, padding
  3. from cryptography.hazmat.backends import default_backend
  4. from typing import Tuple, Optional
  5. import base64
  6. class AsymmetricEncryption:
  7. """非对称加密工具类,使用RSA算法"""
  8. @staticmethod
  9. def generate_key_pair(key_size: int = 2048) -> Tuple[bytes, bytes]:
  10. """
  11. 生成RSA密钥对
  12. Args:
  13. key_size: 密钥大小,默认为2048位
  14. Returns:
  15. Tuple[bytes, bytes]: (私钥PEM格式,公钥PEM格式)
  16. """
  17. # 生成私钥
  18. private_key = rsa.generate_private_key(
  19. public_exponent=65537,
  20. key_size=key_size,
  21. backend=default_backend()
  22. )
  23. # 生成公钥
  24. public_key = private_key.public_key()
  25. # 将私钥序列化为PEM格式
  26. private_pem = private_key.private_bytes(
  27. encoding=serialization.Encoding.PEM,
  28. format=serialization.PrivateFormat.TraditionalOpenSSL,
  29. encryption_algorithm=serialization.NoEncryption()
  30. )
  31. # 将公钥序列化为PEM格式
  32. public_pem = public_key.public_bytes(
  33. encoding=serialization.Encoding.PEM,
  34. format=serialization.PublicFormat.SubjectPublicKeyInfo
  35. )
  36. return private_pem, public_pem
  37. @staticmethod
  38. def encrypt(message: str, public_key_pem: bytes) -> str:
  39. """
  40. 使用公钥加密数据
  41. Args:
  42. message: 要加密的明文
  43. public_key_pem: 公钥PEM格式
  44. Returns:
  45. str: 加密后的base64编码字符串
  46. """
  47. # 加载公钥
  48. public_key = serialization.load_pem_public_key(
  49. public_key_pem,
  50. backend=default_backend()
  51. )
  52. # 加密数据
  53. encrypted = public_key.encrypt(
  54. message.encode('utf-8'),
  55. padding.OAEP(
  56. mgf=padding.MGF1(algorithm=hashes.SHA256()),
  57. algorithm=hashes.SHA256(),
  58. label=None
  59. )
  60. )
  61. # 返回base64编码的加密数据
  62. return base64.b64encode(encrypted).decode('utf-8')
  63. @staticmethod
  64. def decrypt(encrypted_message: str, private_key_pem: bytes) -> str:
  65. """
  66. 使用私钥解密数据
  67. Args:
  68. encrypted_message: 加密后的base64编码字符串
  69. private_key_pem: 私钥PEM格式
  70. Returns:
  71. str: 解密后的明文
  72. """
  73. # 加载私钥
  74. private_key = serialization.load_pem_private_key(
  75. private_key_pem,
  76. password=None,
  77. backend=default_backend()
  78. )
  79. # 解码base64加密数据
  80. encrypted = base64.b64decode(encrypted_message)
  81. # 解密数据
  82. decrypted = private_key.decrypt(
  83. encrypted,
  84. padding.OAEP(
  85. mgf=padding.MGF1(algorithm=hashes.SHA256()),
  86. algorithm=hashes.SHA256(),
  87. label=None
  88. )
  89. )
  90. # 返回解密后的明文
  91. return decrypted.decode('utf-8')
  92. @staticmethod
  93. def save_key_to_file(key_pem: bytes, file_path: str) -> None:
  94. """
  95. 将密钥保存到文件
  96. Args:
  97. key_pem: 密钥PEM格式
  98. file_path: 文件路径
  99. """
  100. with open(file_path, 'wb') as f:
  101. f.write(key_pem)
  102. @staticmethod
  103. def load_key_from_file(file_path: str) -> bytes:
  104. """
  105. 从文件加载密钥
  106. Args:
  107. file_path: 文件路径
  108. Returns:
  109. bytes: 密钥PEM格式
  110. """
  111. with open(file_path, 'rb') as f:
  112. return f.read()
  113. @staticmethod
  114. def generate_key_pair_and_save(private_key_path: str, public_key_path: str, key_size: int = 2048) -> None:
  115. """
  116. 生成密钥对并保存到文件
  117. Args:
  118. private_key_path: 私钥文件路径
  119. public_key_path: 公钥文件路径
  120. key_size: 密钥大小,默认为2048位
  121. """
  122. private_pem, public_pem = AsymmetricEncryption.generate_key_pair(key_size)
  123. AsymmetricEncryption.save_key_to_file(private_pem, private_key_path)
  124. AsymmetricEncryption.save_key_to_file(public_pem, public_key_path)