Cette section explique les raisons d'utiliser des fonctions de hashage pour les mots de passe, ainsi que la façon de le faire efficacement.
Le hashage de mot de passe est l'une des pratiques de sécurité les plus basiques qui doit être effectuée. Sans cela, chaque mot de passe stocké peut être volé si le support de stockage (typiquement une base de données) est compromis. Ce mot de passe peut alors être immédiatement utilisé pour accèder frauduleusement non seulement à votre application mais aussi sur d'autres applications si l'utilisateur utilise le même mot de passe ailleurs.
En appliquant un hashage sur le mot de passe avant de le stocker, vous rendez la tâche d'un attaquant très difficile pour connaitre le mot de passe original, et vous avez toujours la possibilité de comparer le mot de passe hashé à une chaîne reçue.
Il est important de noter que le hashage ne fait que protéger les mots de passe dans la base, pas leur éventuelle interception alors qu'ils sont envoyés à l'application par l'utilisateur, via du code malicieux injecté dans l'application, par exemple.
Les algorithmes de hashage comme MD5, SHA1 et SHA256 sont destinés à être rapides et efficaces. Avec les équipements informatiques modernes, il est devenu facile d'attaquer par force brute la sortie de ces algorithmes pour retrouver la chaîne originale.
C'est la raison pour laquelle de nombreux experts en sécurité considèrent ces algorithmes comme faibles et les déconseillent fortement pour hasher un mot de passe utilisateur.
Lorsqu'on hashe des mots de passe, les deux considérations les plus importantes sont le temps de traitement, et le grain de sel. Plus la puissance de traitement requise est élevée, plus il faudra du temps pour casser le mot de passe en analysant sa sortie.
PHP 5.5 fournit une API native de hashage de mot de passe qui gère à la fois le hashage et la vérification de mots de passe, le tout, de manière totalement sécurisée. Il existe aussi une » bibliothèque pure PHP de compatibilité pour PHP 5.3.7 et suivants.
Une autre option est la fonction crypt(), qui supporte différents algorithmes de hashage en PHP 5.3 et suivants. Lors de l'utilisation de cette fonction, vous avez la garantie que l'algorithme sélectionné est disponible, sachant que PHP contient une implémentation native de chaque algorithme supporté, dans le cas où un ou plusieurs algorithmes n'est pas supporté par votre système.
L'algorithme suggéré à utiliser pour le hashage de mots de passe est Blowfish, qui est aussi l'algorithme par défaut de l'API de hashage de mots de passe, sachant qu'il est significativement plus gourmand en calcul que MD5 ou SHA1, mais plus évolutif.
Notez que si vous utilisez la fonction crypt() pour vérifier un mot de passe, vous devez faire attention aux attaques de synchronisation, en utilisant une constante de temps pour la comparaison. Ni les opérateurs == et === ni la fonction strcmp() n'effectuent de comparaisons en utilisant des constantes de temps. Sachant que la fonction password_verify() le fera pour vous, vous êtes vivement encouragé à utiliser l'API native de hashage de mots de passe lorsque vous le pouvez.
Un grain de sel, ou "salt", en cryptographie, est appliqué durant le processus de hashage pour éliminer la possibilité d'attaques par dictionnaires (hashages enregistrés dans une grande liste et comparés).
En d'autres termes, un grain de sel est une petite donnée additionnelle qui renforce significativement la puissance du hashage pour le rendre beaucoup plus difficile à cracker. Il existe de nombreux services en ligne qui proposent de volumineux dictionnaires de mots de passe avec leur hash. L'utilisation d'un grain de sel rend ces dictionnaires inutiles.
password_hash() va créer un salt aléatoire si vous n'en fournissez pas, et c'est généralement la façon la plus sécurisé et la plus simple.
Lors de l'utilisation de la fonction password_hash() ou de la fonction crypt(), la valeur retournée inclue le salt comme parti du hash généré. Cette valeur devrait être stockée telle quelle dans votre base de données, sachant qu'elle inclue les informations sur la fonction de hashage utilisée et peut donc être fournie directement à la fonction password_verify() ou la fonction crypt() lors de la vérification des mots de passe.
Le diagramme suivant montre le format d'une valeur retournée de la fonction crypt() ou password_hash(). Comme vous pouvez le voir, tout est présent, comme toutes les informations sur l'algorithme et le salt nécessaires pour une future vérification de mots de passe.