Ouvrir aux commentaires et remarques l’algorithme que je prévois pour une future version de Dotclear, a priori la 2.13, pour la vérification et la transition de la gestion des mots de passe vers le système plus robuste offert par les fonctions dédiées incluses à partir de la version 5.5 de PHP.
Pour l’instant, l’algorithme en est là :
if (password_verify($user_input, $pass_hash_from_db))
{
// user logged in
if (password_needs_rehash($pass_hash_from_db, PASSWORD_DEFAULT))
{
$pass_hash = password_hash($user_input, PASSWORD_DEFAULT);
// store $pass_hash in database
…
}
// pwd ok
return true;
} else {
// check if it is still stored as old way
$ret = password_get_info($pass_hash_from_db);
if (is_array($ret) && isset($ret['algo']) && $ret['algo'] == 0) {
// hash not done with password_hash() function
if (dcAuth::crypt($user_input) == $pass_hash_from_db) {
$pass_hash = password_hash($user_input, PASSWORD_DEFAULT);
// store $pass_hash in database
…
// pwd ok
return true;
}
}
}
// pwd KO
return false;
En quelques mots :
On vérifie le mot de passe fourni à la connexion en utilisant le nouveau système. Si c’est ok, on vérifie si le mot à besoin d’être hashé et stocké à nouveau (le système peut évoluer au fur et à mesure des versions de PHP et ça permet de mettre à jour la base en douceur).
Sinon on vérifie si c’est un mot de passe hashé à l’ancienne mode et si le mot de passe correspond. Dans ce cas, on le convertit et on le stocke, du coup à la prochaine connexion on repassera par la première phase uniquement.
Si aucun des deux tests n’aboutit on rejette le mot de passe.
Ça permet de convertir les anciens mot de passe au fur et à mesure des connexions sans devoir passer par la procédure d’oubli des mots de passe disponible sur l’écran de connexion.
Question technique en suspens : pour l’instant j’utilise la valeur par défaut du « coût » CPU du hashage, ce qui donne d’après mes premiers tests en local un temps de réponse d’environ 250 millisecondes. Si vous voulez tester chez vous et éventuellement m’indiquer le temps consommé, voici un exemple de code à utiliser :
$pwd = 'Vive les blogs, vive les copains, et les 42 !';
$start = microtime(true);
$hash = password_hash($pwd, PASSWORD_DEFAULT); //, array('cost' => 10));
$end = microtime(true);
$time = $end - $start;
echo "<p>Elapsed time: $time</p>";
1 De mirovinben -
En local (Wamp - PHP 5.5.12) = 0.078004121780396
En ligne (PHP 5.5.38) = 0.081737995147705
Deux remarques :
(perso j’ai mis )
(tout en continuant à jouer avec un multiblogs tournant sous 5.5).
2 De Franck -
mirovinben une des caractéristiques des chaînes encadrées par des ” est que les variables qui s’y trouvent sont interprétées alors que ce n’est pas le cas avec des ’ et que donc le $time sera bien remplacé par sa valeur.
3 De mirovinben -
Ah ? Ben ça alors… Et dire que je suis passé à côté de ça depuis que je bricole en PHP.
Merki beaucoup.