Dans le domaine de la sécurité des applications, peu de responsabilités sont aussi critiques que la gestion des identifiants utilisateurs. Pendant des décennies, l'industrie s'est fiée à des fonctions de hachage rapides et unidirectionnelles comme MD5 et SHA-1. Cependant, à mesure que les capacités matérielles ont évolué, notamment avec l'avènement des GPU et des ASICs spécialisés, ces algorithmes hérités sont devenus dangereusement obsolètes. Aujourd'hui, stocker des mots de passe à l'aide de simples hachages revient à verrouiller votre porte d'entrée avec un bout de ficelle. Cet article explore les stratégies modernes de hachage des mots de passe, en mettant l'accent sur les fonctions de hachage adaptatives conçues pour résister aux attaques par force brute.
Les principes fondamentaux du stockage sécurisé des mots de passe
Avant de plonger dans des algorithmes spécifiques, il est essentiel de comprendre les trois piliers du stockage sécurisé des mots de passe :
- Fonctionnalité unidirectionnelle : Il doit être computationnellement irréaliste d'inverser le hachage pour récupérer le mot de passe original.
- Sel (Salting) : Chaque mot de passe doit être combiné avec une chaîne de données unique et aléatoire (le sel) avant le hachage. Cela empêche les attaques par tables arc-en-ciel et garantit que deux utilisateurs ayant le même mot de passe auront des hachages différents.
- Adaptabilité (Facteur de travail) : Le processus de hachage doit être délibérément lent et configurable. Cela permet aux développeurs d'augmenter le coût computationnel au fil du temps à mesure que le matériel s'améliore, rendant le coût de l'attaque prohibitif pour les attaquants.
La référence absolue : bcrypt et Argon2
Actuellement, bcrypt et Argon2 sont les normes recommandées. Argon2 est le vainqueur du Concours de hachage de mots de passe (PHC) et est généralement préféré pour les nouveaux projets en raison de sa nature gourmande en mémoire, ce qui le rend résistant aux attaques basées sur les GPU. Bcrypt reste largement pris en charge et constitue un choix sûr si Argon2 n'est pas disponible dans votre pile technologique spécifique.
Pourquoi pas SHA-256 ?
Les développeurs utilisent souvent par erreur SHA-256 ou SHA-512 pour le stockage des mots de passe. Bien qu'il s'agisse de hachages cryptographiques sécurisés, ils sont conçus pour être rapides. Un attaquant peut calculer des milliards de hachages SHA-256 par seconde sur un seul GPU. À l'inverse, les algorithmes de hachage de mots de passe sont conçus pour être lents. Ils intègrent un paramètre de « coût » qui détermine le nombre d'itérations ou de blocs de mémoire utilisés, ralentissant ainsi à la fois les tentatives d'authentification légitimes et les tentatives malveillantes de force brute.
Mise en œuvre pratique en Python
Examinons comment mettre en œuvre un hachage sécurisé des mots de passe à l'aide de la bibliothèque passlib, qui abstrait la complexité des bibliothèques sous-jacentes comme bcrypt ou argon2.
Utilisation de bcrypt
Voici un exemple Python démontrant comment hacher un mot de passe et le vérifier par rapport à un hachage stocké. Notez que nous utilisons un générateur de sel statique pour garantir l'unicité par mot de passe.
import bcrypt
def hash_password(plain_password: str) -> str:
# Générer un sel et hacher le mot de passe
# bcrypt gère automatiquement le sel et l'inclut dans la sortie
salt = bcrypt.gensalt(rounds=12)
hashed = bcrypt.hashpw(plain_password.encode('utf-8'), salt)
return hashed.decode('utf-8')
def verify_password(plain_password: str, hashed_password: str) -> bool:
# Vérifier le mot de passe fourni par rapport au hachage stocké
return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8'))
# Exemple d'utilisation
password = "MySuperSecret123!"
hashed = hash_password(password)
print(f"Hashed Password: {hashed}")
# Vérification
if verify_password(password, hashed):
print("Access Granted")
else:
print("Access Denied")
Utilisation d'Argon2
Argon2id est la variante recommandée, combinant la résistance aux attaques par canaux auxiliaires à la gourmandise en mémoire résistante aux GPU.
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
ph = PasswordHasher(
time_cost=3, # Nombre d'itérations
memory_cost=65536, # Utilisation de la mémoire en KiB
parallelism=4, # Nombre de threads
hash_len=16, # Longueur du hachage de sortie
salt_len=16 # Longueur du sel
)
def hash_argon2(password: str) -> str:
return ph.hash(password)
def verify_argon2(password: str, hash: str) -> bool:
try:
ph.verify(hash, password)
return True
except VerifyMismatchError:
return False
# Exemple d'utilisation
h = hash_argon2("MySuperSecret123!")
print(f"Argon2 Hash: {h}")
print(verify_argon2("MySuperSecret123!", h))
Meilleures pratiques pour les développeurs
- Ne jamais implémenter sa propre cryptographie : Utilisez toujours des bibliothèques éprouvées. Les vulnérabilités liées aux canaux auxiliaires dans les implémentations personnalisées sont courantes.
- Gérer les attaques par chronométrage : Assurez-vous que vos fonctions de vérification utilisent des méthodes de comparaison à temps constant. La plupart des bibliothèques modernes (comme
bcryptetargon2) gèrent cela en interne, mais si vous créez une logique personnalisée, faites preuve de prudence. - Préparez la rotation : À mesure que les normes évoluent, vous devriez prévoir de re-hacher les mots de passe lors de la connexion de l'utilisateur si le hachage actuel utilise un algorithme plus faible ou un facteur de coût inférieur. C'est ce qu'on appelle le « re-hachage différé » (lazy re-hashing).
- Imposer des politiques fortes : Bien que le hachage protège la base de données, l'imposition de politiques de mots de passe fortes (longueur, complexité) réduit la probabilité de réussite d'un craquage hors ligne en cas de violation de données.
Conclusion
Le hachage des mots de passe n'est pas une tâche du type « configurez et oubliez ». Il nécessite une vigilance continue à mesure que la puissance de calcul augmente. En migrant loin des hachages rapides comme SHA-256 et en adoptant des algorithmes gourmands en mémoire comme Argon2 ou adaptatifs comme bcrypt, les développeurs peuvent considérablement élever la barre pour les attaquants. Sécurisez les identifiants de vos utilisateurs aujourd'hui pour prévenir des violations catastrophiques demain.