46 lines
No EOL
1.5 KiB
Python
46 lines
No EOL
1.5 KiB
Python
"""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') |