web-dev-qa-db-fra.com

Comment fonctionne password_hash / password_verify en php?

Pourquoi cet exemple de le PHP donne-t-il des résultats différents à chaque exécution?)

echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);

Et puis, password_verify () sait que TOUS ces hash correspondent à "rasmuslerdorf"! C'est comme par magie pour moi même le doc a clairement dit:

Notez que password_hash () renvoie l'algorithme, le coût et le sel dans le cadre du hachage retourné. Par conséquent, toutes les informations nécessaires pour vérifier le hachage y sont incluses. Cela permet à la fonction de vérification de vérifier le hachage sans avoir besoin d'un stockage séparé pour les informations de sel ou d'algorithme.

Cette fonction est sûre contre les attaques de synchronisation.

echo password_verify ( 'rasmuslerdorf' , '$2y$10$EMawXU7qNS4GzU2Do8bByeb7sSQZxecvmZ6mBrToxsOaY7RMAIGua' );  //=>true
echo password_verify ( 'rasmuslerdorf' , '$2y$10$0vMA2k7LxTBstI/J7clkkuZZ/XtuS1fklVuoM6sl4Fc/aj1avQa5u' ); //=>true
echo password_verify ( 'rasmuslerdorf' , '$2y$10$iuE2EzHMNONAWFKh/4Wyl.dcBxgFaNzAh32va0/gyE4ScqnNr/Uc.' ); //=>true

Que se passe-t-il? Comment password_verify () connaît-il une correspondance de chaîne folle 'rasmuslerdorf' mais pas les pirates?

8
Phung D. An

Le password_hash la fonction, en interne, effectue ces étapes:

  1. Il prend un sel frais et aléatoire à chaque fois que vous l'appelez.
  2. Il applique une fonction de hachage coûteuse qui prend en entrée le sel aléatoire, le mot de passe et d'autres paramètres d'algorithme (par exemple, les facteurs de coût).
  3. Il combine les paramètres de l'algorithme, le sel aléatoire et la sortie de hachage dans une chaîne de sortie qui peut être analysée pour les récupérer individuellement.

Le choix aléatoire dans # 1 est la raison pour laquelle il produit une sortie différente à chaque fois même si vous fournissez la même entrée. La sortie formatée de l'étape # 3 est ce qui permet à password_verify pour connaître le sel choisi au hasard par password_hash.

12
Luis Casillas

La clé pour créer un hachage cryptographique utile est que l'algorithme soit non réversible, mais répétable de manière cohérente. C'est:

  • Étant donné uniquement la sortie de password_hash('rasmuslerdorf'), vous ne pouvez pas récupérer la chaîne 'rasmuslerdorf'
  • Étant donné l'entrée 'rasmuslerdorf', Vous pouvez générer la même sortie comme un appel précédent à password_hash('rasmuslerdorf')

Cela vous permet de vérifier la tentative de mot de passe de l'utilisateur par rapport au hachage, sans jamais pouvoir récupérer son mot de passe.

Le moyen le plus simple d'obtenir un hachage répétable est qu'il ne dépende que de l'entrée - ainsi, password_hash('rasmuslerdorf') retournerait toujours la même valeur. Mais cela signifie qu'un attaquant peut calculer les hachages pour un tas de mots de passe courants et rechercher une correspondance dans une base de données volée.

Donc, à la place, un bon algorithme de hachage ajoute un sel, qui est juste une chaîne aléatoire ajoutée au mot de passe, pour rendre le hachage différent à chaque fois. Afin de répéter la fonction de hachage plus tard et d'obtenir la réponse même, vous devez savoir quel sel a été utilisé lors de son stockage.

Voici ce que password_hash Génère réellement, combiné en une seule chaîne:

  • Le résultat du hachage de l'entrée avec un sel particulier
  • Le sel aléatoire qui a été utilisé
  • L'algorithme de hachage utilisé
  • Toutes les autres options qui contrôlent l'algorithme de hachage (par exemple, le nombre de tours utilisés pour ralentir délibérément le hachage)

Cette sortie sera différente à chaque fois, nous avons donc besoin d'une fonction différente pour répéter le hachage avec l'entrée d'un utilisateur pour voir si nous obtenons la même réponse; voici à quoi sert password_verify:

  • À partir de la chaîne stockée, recherchez l'algorithme, les options et le sel
  • Exécutez l'algorithme de hachage avec ces paramètres et le mot de passe avec lequel l'utilisateur a tenté de se connecter
  • Vérifiez si le résultat correspond à la partie de hachage de la chaîne stockée

Si l'exécution du même algorithme avec les mêmes options et les mêmes résultats de hachage aboutit à un résultat différent, l'utilisateur doit avoir entré un mot de passe incorrect.

3
IMSoP