55 lines
1.5 KiB
Python
55 lines
1.5 KiB
Python
import base64
|
|
import os
|
|
|
|
from Crypto.Cipher import AES
|
|
from Crypto.Util.Padding import pad, unpad
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
|
|
class PhoneEncrypt:
|
|
def __init__(self, key: bytes):
|
|
self.key = key
|
|
if len(self.key) not in (16, 24, 32):
|
|
raise ValueError("AES 密钥必须是 16/24/32 字节")
|
|
|
|
@classmethod
|
|
def from_env(cls):
|
|
hex_key = os.getenv("AES_SECRET_KEY")
|
|
return cls(bytes.fromhex(hex_key))
|
|
|
|
def encrypt(self, phone: str) -> str:
|
|
"""
|
|
加密手机号 -> 返回 Base64 字符串
|
|
:return iv为解密初始数
|
|
ct为加密密文
|
|
"""
|
|
cipher = AES.new(self.key, AES.MODE_CBC) # 随机 IV
|
|
ct_bytes = cipher.encrypt(pad(phone.encode(), AES.block_size))
|
|
iv = base64.b64encode(cipher.iv).decode()
|
|
ct = base64.b64encode(ct_bytes).decode()
|
|
return f"{iv}:{ct}"
|
|
|
|
def decrypt(self, data: str) -> str:
|
|
"""解密 Base64 字符串 -> 返回手机号"""
|
|
iv_b64, ct_b64 = data.split(":")
|
|
iv = base64.b64decode(iv_b64)
|
|
ct = base64.b64decode(ct_b64)
|
|
cipher = AES.new(self.key, AES.MODE_CBC, iv)
|
|
pt = unpad(cipher.decrypt(ct), AES.block_size)
|
|
return pt.decode()
|
|
|
|
|
|
def main():
|
|
phone_encrypt = PhoneEncrypt()
|
|
encrypted = phone_encrypt.encrypt("13568847988")
|
|
print(encrypted)
|
|
|
|
decrypted = phone_encrypt.decrypt(encrypted)
|
|
print(decrypted)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|