57 lines
1.6 KiB
Python

import base64
import os
import secrets
import string
from typing import Tuple
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from app.core.config import settings
def generate_random_key(length: int = 16) -> str:
"""Generate a random access key."""
alphabet = string.ascii_letters + string.digits
return ''.join(secrets.choice(alphabet) for _ in range(length))
def derive_key(password: str, salt: bytes = None) -> Tuple[bytes, bytes]:
"""Derive a key from a password and salt using PBKDF2."""
if salt is None:
salt = os.urandom(16)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
)
key = base64.urlsafe_b64encode(kdf.derive(password.encode()))
return key, salt
def encrypt_content(content: str, password: str = None) -> Tuple[str, bytes]:
"""Encrypt the content using Fernet symmetric encryption."""
if password is None:
password = settings.SECRET_KEY
key, salt = derive_key(password)
cipher = Fernet(key)
encrypted_data = cipher.encrypt(content.encode())
return encrypted_data.decode(), salt
def decrypt_content(encrypted_content: str, salt: bytes, password: str = None) -> str:
"""Decrypt the content using Fernet symmetric encryption."""
if password is None:
password = settings.SECRET_KEY
key, _ = derive_key(password, salt)
cipher = Fernet(key)
decrypted_data = cipher.decrypt(encrypted_content.encode())
return decrypted_data.decode()