Les mots de passe font partie des données les plus critiques d’un système d’information, contrôlant l’accès à l’immense majorité des ressources. Malheureusement ils sont encore trop souvent mal sécurisés, notamment par certains sites web négligents. Il existe pourtant des méthodes pour les stocker de manière sûre qui sont simples à mettre en place et ont fait leurs preuves depuis des années.

Prenons l’exemple d’un site internet sur lequel les internautes peuvent créer un compte et s’authentifier via un couple nom d’utilisateur / mot de passe classique. Le but est d’empêcher un attaquant qui se serait introduit sur le serveur et aurait mis la main sur la liste des mots de passe de les exploiter. Il est important de noter que l’attaquant, une fois qu’il a récupéré ces données, a tout le temps de les manipuler depuis son propre ordinateur. C’est ce que l’on appelle une attaque hors-ligne. Les attaques en ligne, typiquement essayer de nombreux mots de passe possibles directement sur le site, sont empêchées par d’autres moyens comme le verrouillage du compte après “n” tentatives.

Note : quelle que soit la criticité des données contenues sur le site, il est impératif de mettre en place de telles mesures de sécurité. Peu importe que les comptes ne servent qu’à poster des commentaires sur un blog ou accéder à des recettes de cuisine. Gardez en tête que la plupart des utilisateurs ont la mauvaise manie de réutiliser leurs mots de passe sur plusieurs sites différents, et qu’un mot de passe volé sur un site inoffensif peut donner accès à un compte en banque ou à une boite mail.

Une solution assez évidente serait de chiffrer les mots de passe, ainsi l’attaquant qui aurait accès à la liste chiffrée ne verrait qu’une série de bits inintelligible. C’est cependant une mauvaise idée, puisque le serveur qui stocke les mots de passe devra avoir la clé de déchiffrement pour pouvoir les vérifier lorsqu’ils sont entrés par les utilisateurs. Un attaquant qui aurait volé les mots de passe sur le serveur aura donc aussi pu s’emparer de la clé.

La réponse vient d’un autre outil cryptographique : les fonctions de hachage. Au lieu de stocker le mot de passe on stocke son empreinte, et lorsqu’un utilisateur entre son mot de passe on le passe par la même fonction de hachage et on compare le résultat avec ce que l’on a stocké. La propriété fondamentale des fonctions de hachage étant qu’elles sont à sens unique, l’attaquant qui se serait emparé de notre base de données ne pourrait pas s’en servir pour retrouver les mots de passe en clair en dehors d’une attaque par force brute.

Pour contrer ces attaques par forte brute (qui consistent pour l’attaquant à hacher un grand nombre de chaines de caractères jusqu’à trouver une empreinte qui corresponde à un élément de la liste qu’il s’est procurée) il est nécessaire de prendre quelques précautions :

– Utiliser ce que l’on appelle un sel cryptographique, c’est-à-dire une chaîne de caractères aléatoire qu’on concatène au mot de passe avant de le hacher. Ce sel n’a pas besoin d’être gardé secret il suffit juste qu’il soit unique pour chaque utilisateur (le plus simple étant de le générer aléatoirement). Ainsi deux mêmes mots de passe donneront une empreinte différente, ce qui rend plus difficile le travail de l’attaquant. Cela contre notamment l’utilisation de tables de mots de passe pré-hachés (« rainbow tables » et « look-up tables »)

– Privilégier une fonction de hachage lente, et faire de nombreuses itérations. Pour un utilisateur que le serveur mette 0,1s ou 1s à traiter son mot de passe ne change pas grand-chose. Par contre pour l’attaquant qui doit tester un nombre astronomique de possibilités la différence est très significative.

En pratique on utilisera un outil comme “bcrypt”, qui gère automatiquement la génération du sel et permet de paramétrer le nombre d’itérations de la fonction de hachage selon les besoins. “bcrypt” génère un résultat de la forme suivante :

$prefixe$itérations$128bits-sel184bits-empreinte

Par exemple, pour le mot de passe « Password1 » bcrypt donne le résultat suivant :

$2a$10$skhxsW8CKE1nTdHzaPgKhengAtfoLWPaXzPXowIRnXOFqQihG5Zee

La chaîne « $2a$ » est le préfixe propre à l’outil, suivi entre deux signes ‘$’ du nombre d’itérations de la fonction de hachage, puis la concaténation des 128 bits de sel et de l’empreinte de 184 bits.

Enfin, pour vérifier un mot de passe il suffit comme dit précédemment de passer celui qu’a entré l’utilisateur par le même outil et de comparer le résultat avec la valeur stockée.

Sources et lectures supplémentaires :

– http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords

– http://www.darkreading.com/safely-storing-user-passwords-hashing-vs-encrypting/a/d-id/1269374

– http://dustwell.com/how-to-handle-passwords-bcrypt.html

– https://en.wikipedia.org/wiki/Bcrypt

– https://en.wikipedia.org/wiki/Rainbow_table

Emile

Consultant Sécurité