Lors de la création d'un système d'authentification des utilisateurs, la gestion sûre des mots de passe est un problème auquel les développeurs doivent faire attention. La comparaison de mots de passe peut incorrectement entraîner la soumission du système à des menaces de sécurité telles que les attaques de synchronisation. PHP fournit des fonctions intégrées qui peuvent nous aider à gérer en toute sécurité la vérification du mot de passe. Parmi eux, la combinaison de crypte () et hash_equals () est un mode de pratique relativement sûr.
Crypt () est une fonction de chiffrement de PHP, qui est utilisée pour hacher les mots de passe de cryptage basés sur un algorithme (comme Bcrypt , Sha-512 , etc.). Sa syntaxe est la suivante:
string crypt(string $string, string $salt)
Le paramètre SALT détermine l'algorithme de chiffrement et son comportement. Pour les applications modernes, BCrypt est recommandé et le sel approprié peut être généré automatiquement par les méthodes suivantes:
$salt = '$2y$10$' . substr(strtr(base64_encode(random_bytes(16)), '+', '.'), 0, 22);
$hash = crypt('mypassword', $salt);
De nombreux débutants rédigeront le code suivant pour vérifier les mots de passe:
if (crypt($inputPassword, $storedHash) == $storedHash) {
// Connectez-vous avec succès
}
Cela semble réalisable dans la fonction, mais il y a une grave attaque de risque de sécurité. Un attaquant peut progressivement deviner le hachage de mot de passe correct en mesurant la légère différence de temps de réponse du programme.
Pour résoudre le problème des attaques de synchronisation, PHP fournit la fonction hash_equals () depuis 5.6 pour comparer en toute sécurité deux valeurs de hachage:
bool hash_equals(string $known_string, string $user_string)
Il utilise un algorithme de temps constant et ne revient pas à l'avance en fonction du contenu de la chaîne, en évitant les fuites de différence de temps.
<?php
// Supposons que nous obtenons le hachage de mot de passe crypté de la base de données
$storedHash = '$2y$10$9YzyYtVht3tcGEn.7PiF2OlRM0HDTrM7Z5D.yPi8hdm0fJeFVKH4K'; // Dépendre de crypt() Généré bcrypt Hacher
$inputPassword = $_POST['password'] ?? '';
// utiliser crypt() 对utiliser户输入的密码进行Hacher,使utiliser存储Hacher作为 salt
$inputHash = crypt($inputPassword, $storedHash);
// 使utiliser hash_equals() Comparaison de sécurité
if (hash_equals($storedHash, $inputHash)) {
echo "Connectez-vous avec succès!";
} else {
echo "Mot de passe d'erreur!";
}
?>
Bien que Crypt () soit toujours sûr à utiliser, le responsable PHP recommande d'utiliser Password_Hash () et Password_verify () car ils résument le processus de sélection et de comparaison de sécurité de l'algorithme, ce qui le rend plus facile et plus sûr à utiliser. Par exemple:
// 创建密码Hacher
$hash = password_hash('mypassword', PASSWORD_BCRYPT);
// Vérifier le mot de passe
if (password_verify($inputPassword, $hash)) {
echo "Vérification a été adoptée";
}
Cependant, dans certains scénarios (comme le maintien des anciens systèmes ou les besoins spéciaux), la combinaison de crypt () et hash_equals () est toujours une solution acceptable et sûre.
Évitez d'utiliser == OR === Comparer les hachages de mot de passe;
Lorsque vous utilisez le mot de passe de hachage crypt () , vous devez sélectionner correctement le sel et l'algorithme (BCrypt est recommandé);
Utilisez hash_equals () pour des comparaisons sûres pour empêcher les attaques de synchronisation;
S'il n'y a pas de raison spécifique, il est recommandé d'utiliser Password_Hash () et Password_verify () au lieu d'une encapsulation de bas niveau.
La sécurité n'est pas une option mais une exigence lors du traitement des mots de passe utilisateur. L'approche correcte peut non seulement protéger la confidentialité des utilisateurs, mais également améliorer la résistance à l'attaque de l'ensemble du système.