Rappel : les fonctions de hash
Comme vous le savez, il est hors de question de stocker un mot de passe en clair dans une base de données d’authentification, ni même sous une forme chiffrée quelconque. Ce mot de passe doit être stocké sous forme de hash (sorte de cryptage irréversible) : le but est que, si une base de données d’authentification se fait exfiltrer par un voleur, ce dernier n’ait pas accès aux mots de passe et donc aux comptes utilisateurs.
Il existe plusieurs algorithmes de hash. Les plus connus sont MD5, SHA-1, SHA-2. On a l’habitude de dire que seul SHA-2 doit être utilisé, car les 2 précédents ont été « cassés ». Oui… et non. En fait, ça dépend de l’utilisation que vous voulez en faire.
Cassage d'une fonction de hash
Parenthèse : oui, le MD5 et le SHA-1 ont été « cassés ». C’est-à-dire qu’on a trouvé des méthodes systématiques mathématiques permettant de trouver 2 objets différents qui produisent le même hash. Regardez les 2 images ci-dessus. Visuellement, elles sont différentes, il s’agit de Barry White et James Brown. Mais leur MD5 est identique !
Hash et intégrité
On utilise donc le SHA-2 dans une de ses implémentations : SHA-256, SHA-512, SHA-384, SHA-224. On l’utilise pour vérifier une intégrité. C’est-à-dire que quand on l’utilise, c’est pour vérifier qu’un objet transmis est identique entre sa version d’arrivée et sa version de départ. Les utilisations standards sont la transmission d’informations par le réseau (notamment les protocoles chiffrés comme TLS qui incluent par exemple un hash à chaque paquet TCP transmis).
Et les mots de passe dans tout ça ? Lorsqu’un utilisateur tape un login et un mot de passe dans une interface d’authentification quelconque, le logiciel calcule le hash du mot de passe tapé, transmet ce hash par le réseau au serveur d’authentification, et le serveur compare le hash reçu au hash qui avait été stocké au préalable. Si les deux hashes sont identiques, alors le mot de passe est validé et l’utilisateur est authentifié. Clair, simple. Et on comprend pourquoi il faut utiliser SHA-2 et pas les autres algorithmes. Mais alors, d’où vient le « oui et non » du début ?
Password hash
Les algorithmes de type MD5, SHA-1, SHA-2, et bientôt SHA-3 sont utilisés pour vérifier rapidement une intégrité. Rapidement. C’est là qu’intervient l’ergonome : quand un utilisateur tape un mot de passe, vu que c’est un être humain et non pas un logiciel informatique, si le temps de vérification du mot de passe est beaucoup plus lent, l’utilisateur ne s’en apercevra pas (l’utilisateur est prêt à attendre 1 seconde lors d’une telle vérification). Donc lorsqu’on veut générer des hashes de mots de passe, d’autres algorithmes sont préférables. Au lieu d’utiliser des fonctions de « cryptographic hash » qui sont optimisées pour être solides et rapides, on utilisera plutôt des fonctions de « password hash » pour lesquelles la lenteur est un critère de choix :
- Argon2id (mémoire >= 32 Mo, tours >= 2, parallélisme >= 2)
- scrypt / yescript (mémoire >= 32 Mo, rounds >= 4, parallélisme >= 1)
- bcrypt (utilisé par PHP avec
password_hash()
etpassword_verify()
) - PBKDF2-SHA512 (itérations = 85000)
Sources
https://www.mscs.dal.ca/~selinger/md5collision/
https://natmchugh.blogspot.com/2014/10/how-i-created-two-images-with-same-md5.html
https://en.wikipedia.org/wiki/Bcrypt
https://en.wikipedia.org/wiki/Scrypt
https://security.blogoverflow.com/2013/09/about-secure-password-hashing/
http://security.stackexchange.com/a/3993