crypto_utils.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import hashlib
  2. import json
  3. from cryptography.fernet import Fernet
  4. import logging
  5. import os
  6. logger = logging.getLogger(__name__)
  7. def get_api_key_hash(api_key: str) -> str:
  8. """Generate a hash of the API key for directory naming."""
  9. return hashlib.sha256(api_key.encode()).hexdigest()[:16]
  10. def is_dev_mode() -> bool:
  11. """Check if we're in dev mode (no encryption)."""
  12. return os.getenv("LETTA_SWITCHBOARD_DEV_MODE", "").lower() in ("true", "1", "yes")
  13. def get_encryption_key() -> bytes:
  14. """Get or generate encryption key for JSON encryption."""
  15. key = os.getenv("LETTA_SWITCHBOARD_ENCRYPTION_KEY")
  16. if is_dev_mode():
  17. logger.warning("🔓 DEV MODE: Encryption disabled - files stored in plaintext")
  18. return b"dev-mode-no-encryption"
  19. if not key:
  20. logger.warning("LETTA_SWITCHBOARD_ENCRYPTION_KEY not set, generating temporary key")
  21. key = Fernet.generate_key().decode()
  22. return key.encode()
  23. def encrypt_json(data: dict, encryption_key: bytes) -> bytes:
  24. """Encrypt a JSON object (or return plaintext in dev mode)."""
  25. json_bytes = json.dumps(data, default=str, indent=2).encode()
  26. if is_dev_mode():
  27. return json_bytes
  28. fernet = Fernet(encryption_key)
  29. return fernet.encrypt(json_bytes)
  30. def decrypt_json(encrypted_data: bytes, encryption_key: bytes) -> dict:
  31. """Decrypt an encrypted JSON object (or parse plaintext in dev mode)."""
  32. if is_dev_mode():
  33. return json.loads(encrypted_data)
  34. fernet = Fernet(encryption_key)
  35. json_bytes = fernet.decrypt(encrypted_data)
  36. return json.loads(json_bytes)