En PHP, les fonctions Crypt sont souvent utilisées pour le hachage du mot de passe. Il permet à la sécurité du hachage d'être améliorée par la valeur du sel (sel) pour éviter les risques de sécurité tels que les attaques de table arc-en-ciel. Cependant, de nombreux développeurs sont habitués aux valeurs de sel à code dur lors de l'utilisation de la crypte , ce qui peut entraîner des risques de sécurité. Cet article discutera en détail de la façon d'éviter les valeurs de sel à code dur, améliorant ainsi la sécurité du stockage de mot de passe.
Les valeurs de sel à code dur se réfèrent à l'écriture de chaînes de sel fixes directement dans le code, telles que:
$salt = '$6$rounds=5000$fixedsaltstring$';
$hash = crypt($password, $salt);
Il y a des risques évidents à le faire:
Réutilisation de la valeur de sel : tous les hachages de mot de passe de tous les utilisateurs utilisent le même sel et l'attaquant peut pré-calculer l'attaque en pré-calculant l'attaque.
Valeur de sel exposée : si le code source est divulgué et que l'attaquant connaît le sel, la difficulté de la fissuration du hachage sera considérablement réduite.
Difficile à évoluer : si vous avez besoin de modifier la stratégie de sel, la modification de la partie codée dure est extrêmement inflexible.
Pour éviter les problèmes ci-dessus, il est recommandé de générer dynamiquement des sels uniques et sûrs. Voici quelques points clés:
La fonction Random_Bytes () de PHP peut générer des octets aléatoires de haute intensité, et le sel peut être généré en combinant la base64 ou un codage similaire.
function generateSalt($length = 16) {
$bytes = random_bytes($length);
return substr(strtr(base64_encode($bytes), '+', '.'), 0, $length);
}
Différents algorithmes ont des exigences différentes pour les formats de sel. Prenant SHA-512 ( 6 $ ) à titre d'exemple, le format est:
$6$rounds=5000$saltstring$
Combiné avec du sel dynamique:
$saltString = '$6$rounds=5000$' . generateSalt() . '$';
$hash = crypt($password, $saltString);
Le hachage renvoyé par la crypte contient des informations sur le sel. Lors du stockage, vous n'avez besoin de stocker le hachage complet sans économiser le sel séparément.
Lors de la vérification, appelez la crypte directement avec le mot de passe d'entrée et le hachage de stockage et comparez les résultats:
function verifyPassword($inputPassword, $storedHash) {
return crypt($inputPassword, $storedHash) === $storedHash;
}
<?php
// Générer du sel dynamique
function generateSalt($length = 16) {
$bytes = random_bytes($length);
return substr(strtr(base64_encode($bytes), '+', '.'), 0, $length);
}
// Créer un hachage de mot de passe
function createHash($password) {
$salt = '$6$rounds=5000$' . generateSalt() . '$';
return crypt($password, $salt);
}
// Vérifier le mot de passe
function verifyPassword($inputPassword, $storedHash) {
return crypt($inputPassword, $storedHash) === $storedHash;
}
// Exemple d'utilisation
$password = 'mypassword123';
$hash = createHash($password);
echo "Valeur de hachage: $hash\n";
if (verifyPassword('mypassword123', $hash)) {
echo "La vérification du mot de passe a réussi!\n";
} else {
echo "La vérification du mot de passe a échoué!\n";
}
?>
Éviter les valeurs de sel à code dur peut considérablement améliorer la sécurité du hachage du mot de passe. En utilisant la fonction de génération de nombres aléatoires de PHP, une valeur de sel unique est créée dynamiquement et un hachage complet est stocké dans la base de données, qui peut résister efficacement à une variété de méthodes d'attaque.