Une fonction de hachage retourne toujours la même valeur pour la même chaîne d'entrée. Disons que mon utilisateur (Alice) a le mot de passe secret
. Le hachage secret
l'aide md5()
conduit à la suite de hachage
5ebe2294ecd0e0f08eab7690d2a6ee69
À l'aide d'un dictionnaire (une liste de mots courants et mot de passe) ou l'un des différents sites que vous offrir ce service, l'attaquant (Mallory) peut facilement trouver le mot de passe est secret lorsqu'il voit dans son dictionnaire qu' 5ebe2294ecd0e0f08eab7690d2a6ee69 = secret
.
Le processus de salage avant le hachage rend plus difficile d'utiliser une attaque par dictionnaire sans connaître votre sel. Considérez les points suivants:
<?php
$salt = '@!#%$@#$@SADLkwod,sdaDwqksjaoidjwq@#@!';
$hash = md5($salt . 'secret');
Le résultant de hachage est désormais b58ad809eece17322de5024d79299f8a
mais Alice mot de passe est toujours secret
. Maintenant, si Mallory obtient ses mains sur le salé de hachage, les chances sont qu'elle ne va pas trouver la réponse dans son dictionnaire. Si elle le fait, le dictionnaire lui donner la mauvaise réponse.
Ne conservez jamais statique de sel dans votre base de données. De préférence, les stocker avec votre configuration de l'application (qui d'ailleurs ne devrait pas être disponible sur le web).
Si vous allez utiliser une dynamique de sel, vous allez avoir besoin d'utiliser la base de données. Utiliser une valeur non nulle de la colonne de l'existant valide les données de votre sel (blowfish-chaîne cryptée de nom d'utilisateur basée sur un secret de la clé de chiffrement est généralement cryptographique sécurisé). Ne pas utiliser une colonne séparée pour le sel. Si vous ne pouvez pas utiliser une colonne existante, incorporer le sel dans la même colonne que votre hash. Par exemple, utiliser les 32 premiers caractères de votre 128-bits de sel, puis les 40 dernières pour votre 160 bits de hachage. La fonction suivante va générer un tel hash:
function seeded_sha1($string, $seed_bits) {
if(($seed_bits % 8) != 0) {
throw new Exception('bits must be divisible by 8');
}
$salt = '';
for($i = 0; $i < $seed_bits; $i+=8) {
$salt .= pack('c', mt_rand());
}
$hexsalt = unpack('h*hex', $salt);
return $hexsalt['hex'] . sha1($salt . $string);
}
function compare_seeded_sha1($plain, $hash) {
$sha1 = substr($hash, -40);
$salt = pack('h*', substr($hash, 0, -40));
$plain_hash = sha1($salt . $plain);
return ($plain_hash == $sha1);
}
Si un intrus pénètre dans votre base de données en utilisant SQL injection, au moins les hachages il/elle récupère ne sera pas utile car il/elle n'aura pas accès à la configuration de votre application. Si votre serveur est enracinée, c'est assez beaucoup de jeu sur n'importe ce que vous faites.
Remarque: Il existe d'autres types d'attaques possibles sur md5()
qui est pourquoi vous utilisez le plus sûr algorithme de hachage, sha1()
par exemple. Ou, mieux encore, utiliser le Portable PHP hachage de mot de passe-cadre, qui a été conçu avec la sécurité à l'esprit et est rétro-compatible avec pratiquement n'importe quel version de PHP.
require('PasswordHash.php');
$pwdHasher = new PasswordHash(8, FALSE);
// $hash is what you would store in your database
$hash = $pwdHasher->HashPassword( $password );
// $hash would be the $hashed stored in your database for this user
$checked = $pwdHasher->CheckPassword($password, $hash);
if ($checked) {
echo 'password correct';
} else {
echo 'wrong credentials';
}