Sécurité · 9 septembre 2026

Sécurité des mots de passe pour les développeurs — quoi stocker, quoi hacher et quoi ne jamais, jamais faire

Des mots de passe en clair dans une base de données sont une violation qui attend de se produire. Voici à quoi ressemble le stockage moderne des mots de passe, pourquoi 'juste hacher avec SHA-256' ne suffit pas, et quoi faire à la place.

Chaque divulgation de violation de données suit la même arche : « Nous prenons la sécurité au sérieux. » Ensuite, vous lisez les détails et découvrez que les mots de passe étaient stockés en clair, ou hachés avec MD5, ou chiffrés avec une clé qui se trouvait dans la même base de données. Le problème de stockage des mots de passe est résolu — les algorithmes existent, les bibliothèques existent, la documentation existe — et pourtant les développeurs font encore mal les choses.

Cet article couvre quoi stocker, quoi ne pas stocker, la différence entre hachage et chiffrement, et pourquoi SHA-256(password) n’est pas un hachage de mot de passe.

La règle : ne stockez jamais en clair

Si votre base de données est compromise et que vous avez des mots de passe en clair, chaque utilisateur qui réutilise ce mot de passe sur d’autres sites est maintenant compromis. Pas seulement votre site — leur e-mail, leur banque, leurs réseaux sociaux. Le stockage de mots de passe en clair n’est pas un problème de sécurité. C’est un problème moral.

Stockez un hachage. Toujours.

Hachage vs chiffrement

Le hachage est une transformation unidirectionnelle. Vous ne pouvez pas l’inverser. Étant donné hash(password), vous ne pouvez pas récupérer password. Vous ne pouvez que vérifier : hacher l’entrée et comparer.

Le chiffrement est une transformation bidirectionnelle. Étant donné encrypt(password, key), vous pouvez récupérer password avec la clé. Si la clé est compromise, chaque mot de passe est compromis.

Hachez les mots de passe. Ne les chiffrez jamais. Si vous devez récupérer le clair (vous n’en avez pas besoin), vous résolvez le mauvais problème.

Pourquoi SHA-256 ne suffit pas

Une erreur courante : hash = SHA-256(password). C’est rapide, c’est bien connu, et c’est incorrect pour les mots de passe.

Le problème est la vitesse. SHA-256 sur un GPU moderne traite des milliards de hachages par seconde. Un attaquant avec une base de données de hachages de mots de passe SHA-256 peut essayer chaque mot de passe courant, chaque mot de dictionnaire, chaque permutation, en quelques minutes.

Les algorithmes de hachage de mots de passe sont délibérément lents. Ils utilisent l’étirement de clés — des milliers d’itérations d’une fonction de hachage — pour rendre les attaques par force brute impraticables :

  • bcrypt — le standard depuis 1999. Facteur de coût ajustable. Mot de passe + sel → hachage. Chaque langage majeur a une bibliothèque.
  • scrypt — résistant à la mémoire. Nécessite de grandes quantités de RAM pour calculer, rendant les attaques GPU plus difficiles.
  • Argon2 — gagnant du Concours de Hachage de Mots de Passe (2015). Résistant à la mémoire, temps et coûts mémoire configurables. La meilleure pratique actuelle.
  • PBKDF2 — recommandé par NIST, largement disponible, utilise des itérations HMAC. Moins résistant à la mémoire qu’Argon2 mais bien testé.

Utilisez bcrypt, scrypt ou Argon2. N’inventez pas votre propre schéma. Ne hachez pas une fois avec SHA-256 et ne l’appelez pas terminé.

Sel : pourquoi chaque mot de passe en a besoin d’un unique

Un sel sont des données aléatoires ajoutées au mot de passe avant le hachage. Sans sel, deux utilisateurs avec le même mot de passe produisent le même hachage. Un attaquant peut pré-calculer des hachages pour les mots de passe courants (un tableau arc-en-ciel) et les correspondre à votre base de données.

Avec un sel unique par utilisateur, chaque hachage est différent même si les mots de passe sont identiques. Les tableaux arc-en-ciel ne fonctionnent pas. L’attaquant doit forcer brutalement chaque mot de passe individuellement.

Les fonctions modernes de hachage de mots de passe (bcrypt, Argon2) génèrent un sel aléatoire automatiquement. Vous n’avez pas besoin de gérer les sels séparément. Passez le mot de passe à la fonction de hachage, et elle gère le reste.

Quoi stocker

Pour chaque utilisateur, stockez :

  • Le hachage du mot de passe (la sortie de bcrypt/Argon2, qui inclut le sel et les paramètres de coût)
  • L’algorithme de hachage (bcrypt, argon2, etc.)
  • Les paramètres de coût (tours bcrypt, mémoire/temps Argon2)

Ne stockez PAS :

  • Le mot de passe en clair
  • Le sel séparément (la sortie de la fonction de hachage l’inclut)
  • Une « clé de chiffrement » qui pourrait déchiffrer le mot de passe
  • Des indices de mot de passe (ils divulguent des informations)

La sortie de hachage de bcrypt ressemble à : $2b$12$LJ3m4ys3GzF4VQ.YOUR.HASH.HERE. Le $2b$ identifie l’algorithme, 12 est le facteur de coût, et le reste est sel + hachage. Pour vérifier une tentative de connexion, hachez le mot de passe soumis avec les mêmes paramètres et comparez.

Facteurs de coût

Le facteur de coût de bcrypt détermine la vitesse du hachage. Chaque incrément double le temps de calcul :

  • Coût 10 : ~10ms par hachage (rapide pour les utilisateurs, rapide pour les attaquants)
  • Coût 12 : ~40ms par hachage (raisonnable)
  • Coût 14 : ~160ms par hachage (lent pour les attaquants, perceptible pour les utilisateurs)
  • Coût 16 : ~640ms par hachage (trop lent pour la plupart des flux de connexion)

Le point idéal en 2026 : bcrypt coût 12-14, Argon2 avec 64MB+ de mémoire et 3+ itérations. L’objectif est de rendre chaque tentative de hachage assez lente pour que la force brute de milliards de mots de passe prenne des années, mais assez rapide pour qu’un utilisateur ne remarque pas de retard à la connexion.

Limitation de débit

Le hachage seul ne suffit pas. Si un attaquant peut essayer des millions de mots de passe par seconde contre votre endpoint de connexion, même bcrypt ne vous sauvera pas.

Limitez les tentatives de connexion. Après 5-10 tentatives échouées depuis la même IP ou le même compte, bloquez le compte temporairement ou exigez un CAPTCHA. Cela limite les attaques par force brute à un filet.

Ne révélez pas si le nom d’utilisateur ou le mot de passe était incorrect. « Nom d’utilisateur ou mot de passe invalide » est plus sûr que « Aucun compte trouvé avec cet e-mail. » Ce dernier indique à un attaquants quels noms d’utilisateur existent.

Ajoutez le verrouillage de compte après des échecs répétés. Après 10-20 tentatives échouées, bloquez le compte pendant 15 minutes ou exigez une vérification par e-mail pour débloquer.

Génération de mots de passe

Lors de la génération de mots de passe (pour les utilisateurs, les clés API, les tokens) :

  • Minimum 12 caractères. 8 ne suffit plus contre le matériel moderne.
  • Incluez majuscules, minuscules, chiffres et symboles. Mais la longueur compte plus que la complexité.
  • Utilisez un CSPRNG (générateur de nombres pseudo-aléatoires cryptographiquement sûr). Math.random() n’est pas sûr.
  • Ne générez jamais de motifs prévisibles. Password1! semble complexe mais est trivial à deviner.

Le meilleur mot de passe est une chaîne générée aléatoirement par un CSPRNG. Utilisez un gestionnaire de mots de passe pour le stocker. Ne demandez pas aux utilisateurs de mémoriser des mots de passe complexes — donnez-leur un mot de passe généré et laissez le gestionnaire le gérer.

Erreurs courantes

  • Hacher une fois avec SHA-256 ou MD5 — trop rapide, pas de sel, trivial à forcer brutalement.
  • Utiliser un sel statique — si chaque utilisateur partage le même sel, les tableaux arc-en-ciel fonctionnent.
  • Stocker le sel séparément — si le sel est dans une table différente, un attaquant qui compromet la base de données obtient les deux.
  • Chiffrer au lieu de hacher — si vous pouvez déchiffrer le mot de passe, un attaquant avec la clé peut aussi.
  • Pas de limitation de débit — même bcrypt est vulnérable aux tentatives de connexion illimitées.
  • Révéler si un nom d’utilisateur existe — aide les attaquants à énumérer les comptes valides.
  • Utiliser Math.random() pour la génération de mots de passe — prévisible, pas cryptographiquement sûr.

Référence rapide

Faites Ne faites pas
Utilisez bcrypt, Argon2 ou scrypt Utilisez SHA-256 ou MD5
Laissez la bibliothèque gérer les sels Gérez les sels vous-même
Limitez les tentatives de connexion Autorisez les tentatives de mot de passe illimitées
Générez des mots de passe avec CSPRNG Utilisez Math.random()
Stockez uniquement le hachage Stockez des mots de passe en clair ou chiffrés
Dites « identifiants invalides » Dites « mot de passe incorrect »

Essayez

Si vous devez générer un mot de passe aléatoire sûr ou hacher une chaîne pour des tests, utilisez un outil basé sur navigateur pour que l’opération reste locale. Votre mot de passe ne doit jamais toucher un serveur pour une tâche de génération simple.