"""Chiffrement/déchiffrement Fernet pour les identifiants ENT77. Utilise la SECRET_KEY Flask comme clé dérivée (via PBKDF2). Les identifiants ne sont JAMAIS stockés en clair en DB. """ import base64 import hashlib import os from cryptography.fernet import Fernet from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC def _derive_key(secret_key: str, salt: bytes = b'gmao-ent77-salt-v1') -> bytes: """Dérive une clé Fernet valide (32 bytes url-safe base64) depuis la SECRET_KEY Flask.""" kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=480_000, ) key = kdf.derive(secret_key.encode('utf-8')) return base64.urlsafe_b64encode(key) def get_fernet(app=None): """Retourne une instance Fernet configurée avec la clé dérivée de la SECRET_KEY.""" if app is None: from flask import current_app app = current_app secret_key = app.config.get('SECRET_KEY', 'dev-key-change-in-production') key = _derive_key(secret_key) return Fernet(key) def encrypt_value(plaintext: str, app=None) -> bytes: """Chiffre une chaîne et retourne le ciphertext (bytes).""" f = get_fernet(app) return f.encrypt(plaintext.encode('utf-8')) def decrypt_value(ciphertext: bytes, app=None) -> str: """Déchiffre du ciphertext et retourne la chaîne en clair.""" f = get_fernet(app) return f.decrypt(ciphertext).decode('utf-8')