""" MCLogger – Kryptographie-Utilities - Passwort-Hashing: PBKDF2-HMAC-SHA256 mit Salt (pro Nutzer) + Pepper (global, via ENV) - DB-Credential-Verschlüsselung: Fernet (symmetrisch, Schlüssel via ENV) """ import hashlib import os from cryptography.fernet import Fernet from config import Config # ───────────────────────────────────────────────────────────── # Passwort-Hashing # ───────────────────────────────────────────────────────────── def generate_salt() -> str: """Generiert einen zufälligen 32-Byte Hex-Salt.""" return os.urandom(32).hex() def hash_password(password: str, salt: str) -> str: """ Hasht ein Passwort mit PBKDF2-HMAC-SHA256. Verwendet: salt (pro Nutzer) + pepper (global aus ENV) """ dk = hashlib.pbkdf2_hmac( "sha256", password.encode("utf-8"), (salt + Config.PASSWORD_PEPPER).encode("utf-8"), iterations=260_000, ) return dk.hex() def verify_password(password: str, salt: str, stored_hash: str) -> bool: """Prüft ob ein Passwort korrekt ist.""" return hash_password(password, salt) == stored_hash # ───────────────────────────────────────────────────────────── # Fernet-Verschlüsselung (für DB-Zugangsdaten) # ───────────────────────────────────────────────────────────── def _get_fernet() -> Fernet: key = Config.FERNET_KEY if not key: raise RuntimeError( "FERNET_KEY ist nicht gesetzt! " "Generieren: python -c \"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())\"" ) if isinstance(key, str): key = key.encode() return Fernet(key) def encrypt_str(plaintext: str) -> str: """Verschlüsselt einen String mit Fernet.""" return _get_fernet().encrypt(plaintext.encode("utf-8")).decode("utf-8") def decrypt_str(ciphertext: str) -> str: """Entschlüsselt einen Fernet-verschlüsselten String.""" return _get_fernet().decrypt(ciphertext.encode("utf-8")).decode("utf-8")