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?
Le password_hash
la fonction, en interne, effectue ces étapes:
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
.
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:
password_hash('rasmuslerdorf')
, vous ne pouvez pas récupérer la chaîne 'rasmuslerdorf'
'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:
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
:
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.