import base64 import os from cryptography.hazmat.primitives.ciphers.aead import AESGCM NONCE_LEN = 12 class SecretBox: def __init__(self, key: bytes): self._aes = AESGCM(key) def encrypt(self, plaintext: str, context: str) -> str: nonce = os.urandom(NONCE_LEN) ciphertext = self._aes.encrypt(nonce, plaintext.encode(), context.encode()) return base64.b64encode(nonce + ciphertext).decode() def decrypt(self, token: str, context: str) -> str: raw = base64.b64decode(token) return self._aes.decrypt(raw[:NONCE_LEN], raw[NONCE_LEN:], context.encode()).decode() def generate_master_key() -> str: return base64.b64encode(os.urandom(32)).decode()