import os from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import padding class AESCipher: def __init__(self, key: bytes) -> None: self.key = key self.backend = default_backend() def encrypt(self, plain_text: str) -> bytes: # generate a random initialization vector iv = os.urandom(16) cipher = Cipher(algorithms.AES(self.key), modes.CFB(iv), backend=self.backend) encryptor = cipher.encryptor() # fill the last block with padding padder = padding.PKCS7(algorithms.AES.block_size).padder() padded_data = padder.update(plain_text.encode()) + padder.finalize() encrypted = encryptor.update(padded_data) + encryptor.finalize() return iv + encrypted def decrypt(self, encrypted_text: bytes) -> str: # get the initialization vector and the encrypted data iv = encrypted_text[:16] encrypted_data = encrypted_text[16:] cipher = Cipher(algorithms.AES(self.key), modes.CFB(iv), backend=self.backend) decryptor = cipher.decryptor() # remove the padding decrypted_padded = decryptor.update(encrypted_data) + decryptor.finalize() unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() decrypted = unpadder.update(decrypted_padded) + unpadder.finalize() return decrypted.decode()