crypto.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
  2. from cryptography.hazmat.backends import default_backend
  3. import base64
  4. import os
  5. from .config import settings
  6. def get_encrypt_key() -> bytes:
  7. """获取加密密钥"""
  8. key = settings.oss.parse_encrypt_key
  9. return key.encode('utf-8')[:16].ljust(16, b'\0')
  10. def encrypt_url(plain_url: str) -> str:
  11. """加密URL - 使用CFB模式与Go版本一致"""
  12. if not plain_url:
  13. return ""
  14. try:
  15. key = get_encrypt_key()
  16. plain_bytes = plain_url.encode('utf-8')
  17. # 生成随机IV
  18. iv = os.urandom(16)
  19. # 使用CFB模式
  20. cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=default_backend())
  21. encryptor = cipher.encryptor()
  22. # 加密
  23. encrypted = encryptor.update(plain_bytes) + encryptor.finalize()
  24. # IV + 密文
  25. ciphertext = iv + encrypted
  26. return base64.urlsafe_b64encode(ciphertext).decode('utf-8')
  27. except Exception as e:
  28. print(f"加密失败: {e}")
  29. return ""
  30. def decrypt_url(encrypted_url: str) -> str:
  31. """解密URL - 使用CFB模式与Go版本一致"""
  32. if not encrypted_url:
  33. return ""
  34. try:
  35. key = get_encrypt_key()
  36. # Base64解码
  37. ciphertext = base64.urlsafe_b64decode(encrypted_url)
  38. if len(ciphertext) < 16:
  39. raise ValueError("密文长度不足")
  40. # 提取IV和密文
  41. iv = ciphertext[:16]
  42. encrypted = ciphertext[16:]
  43. # 使用CFB模式解密
  44. cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=default_backend())
  45. decryptor = cipher.decryptor()
  46. decrypted = decryptor.update(encrypted) + decryptor.finalize()
  47. return decrypted.decode('utf-8')
  48. except Exception as e:
  49. print(f"解密失败: {e}")
  50. return ""