from nacl.secret import SecretBox from nacl.utils import random import base64 import json class CryptoManager: def __init__(self, secret_key: str): key_bytes = secret_key.encode('utf-8') self.key = bytes([key_bytes[i % len(key_bytes)] for i in range(32)]) def encrypt(self, data: bytes) -> dict: box = SecretBox(self.key) nonce = random(SecretBox.NONCE_SIZE) encrypted_msg = box.encrypt(data, nonce) ciphertext_only = encrypted_msg[SecretBox.NONCE_SIZE:] return { 'ciphertext': base64.b64encode(ciphertext_only).decode('utf-8'), 'nonce': base64.b64encode(nonce).decode('utf-8') } def decrypt(self, ciphertext: str, nonce: str) -> bytes: box = SecretBox(self.key) ciphertext_bytes = base64.b64decode(ciphertext) nonce_bytes = base64.b64decode(nonce) decrypted = box.decrypt(ciphertext_bytes, nonce_bytes) return decrypted def encrypt_json(self, data: dict) -> dict: json_bytes = json.dumps(data).encode('utf-8') return self.encrypt(json_bytes) def decrypt_json(self, ciphertext: str, nonce: str) -> dict: plaintext = self.decrypt(ciphertext, nonce) return json.loads(plaintext.decode('utf-8'))