Vortex-Flux / src /core /auth.py
jaimalklyde's picture
Claude Sonnet 5
Securite et fiabilite : corrections sur l'ensemble du simulateur/octroi/notifications
397b23d
Raw History Blame Contribute Delete
2.07 kB
"""
AUTHENTIFICATION — HASHAGE DES MOTS DE PASSE (PBKDF2-HMAC-SHA256)
====================================================================
Format de stockage attendu dans le secret USERS pour un compte migre :
"pbkdf2_sha256$<iterations>$<sel_hex>$<hash_hex>"
Un compte pas encore migre garde son mot de passe en clair comme valeur
dans USERS : verify_password() reste compatible avec ce cas (comparaison
en temps constant quand meme) pour ne pas bloquer les connexions existantes
au deploiement, mais ce n'est qu'un pont temporaire — hash_password() doit
etre utilise pour generer la nouvelle valeur a coller dans le secret des
que possible, compte par compte.
"""
import hashlib
import hmac
import os
_ALGO = "pbkdf2_sha256"
_ITERATIONS = 600_000
def hash_password(password: str, iterations: int = _ITERATIONS) -> str:
"""Genere la valeur a stocker dans le secret USERS pour ce mot de passe."""
salt = os.urandom(16)
digest = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, iterations)
return f"{_ALGO}${iterations}${salt.hex()}${digest.hex()}"
def verify_password(stored_value: str, provided_password: str) -> bool:
"""Compare en temps constant. Accepte soit un hash pbkdf2_sha256$...
(compte migre), soit, a titre transitoire, l'ancien mot de passe en
clair encore present dans le secret (compte pas encore migre)."""
stored_value = str(stored_value or "")
provided_password = str(provided_password or "")
if stored_value.startswith(f"{_ALGO}$"):
try:
_, iterations_str, salt_hex, hash_hex = stored_value.split("$", 3)
iterations = int(iterations_str)
salt = bytes.fromhex(salt_hex)
expected = bytes.fromhex(hash_hex)
except (ValueError, IndexError):
return False
computed = hashlib.pbkdf2_hmac("sha256", provided_password.encode("utf-8"), salt, iterations)
return hmac.compare_digest(computed, expected)
return hmac.compare_digest(stored_value.encode("utf-8"), provided_password.encode("utf-8"))