Mots de passe sécurisés

PHP Ajouter un commentaire

PHP fournit en standard des mécanismes de cryptage tels que MD5 ou SHA1. Alors, plutôt que de laisser les mots de passe en clair, voici un bref article pour sécuriser au mieux les intérêts de vos utilisateurs.

Petit rappel : MD5 et SHA1 sont des mécanismes de cryptage unidirectionnels, c’est-à-dire qu’une fois la chaîne cryptée, il n’y a pas de possibilité de connaître sa version originelle. C’est donc pratique pour gérer des mots de passe. La saisie utilisateur lors de son authentification est récupérée, le cryptage est appliqué sur cette saisie et comparée avec la version cryptée. Si les deux hachages correspondent, le mot de passe est valide.

Une limite forte apparait : une chaine en clair passée à la moulinette d’un MD5 par exemple donne toujours le même hachage au final. Le problème devient alors exploitable pour des pirates en recréant un dictionnaire de mots de passe communs hachés, les utilisateurs étant dans la grand majorité des cas peu inventifs (date d’anniversaire, nom du chien, prénom de la femme ou du mari…). Résultat : crypter ne fait que retarder l’échéance de voir ses mots de passe divulgués.

Une solution proposée par le PHP Security Consortium en 2005 consiste à gérer une clé de 9 caractères avec MD5, et de l’utiliser comme sel pour le cryptage du mot de passe avec SHA1. On concatène la clé au début du hachage et le mot de passe stocké en base est donc de la forme Salt (9 caractères) + Hachage SHA1 (40 caractères).
Il permet donc d’éviter les attaques de type dictionnaire.

Voici la fonction à utiliser pour générer le hachage :

define('SALT_LENGTH', 9);
 
function generate_hash($plainText, $salt = null)
{
    if ($salt === null) {
        $salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
    } else {
        $salt = substr($salt, 0, SALT_LENGTH);
    }
 
    return $salt . sha1($salt . $plainText);
}
// Pour générer le mot de passe
$passcrypte = generate_hash('abc123'); 
 
// Pour tester le mot de passe avec une saisie
$testpass = generate_hash($_POST['password'], $passcrypte);
 
if ($testpass == $passcrypte) {
    echo 'Le mot de passe est correct !';
}

6 Réponses to “Mots de passe sécurisés”

  1. Ze Says:

    Je conseille la lib phpass de chez Openwall.com ( http://www.openwall.com/phpass/ ) pour gérer ce genre de chose.

  2. Christophe Buguet Says:

    Merci pour votre retour. Je ne connaissais pas, ca semble très bien fait.

  3. Hugo Says:

    Tu as aussi crypt() qui gère les salts en natif. J’ai fait un article il y’a quelques semaines sur la sécurisation des passwords. Il se trouve ici :

    http://www.apprendre-php.com/tutoriels/tutoriel-35-securiser-les-mots-de-passe-avec-les-hashs-et-les-salts.html

    ++

  4. Eric Says:

    Regardez aussi surtout crypt(), qui est fait pour ça. Pour peu que votre système le supporte (ce qui est probablement le cas), vous aurez un hachage par md5 ou sha1, et un grain de sel réellement aléatoire suffisament long.

    Outre le fait que c’est natif, ça utilise les fonctions présentes sur le système donc si un jour sha1/md5 sont jugés insuffisants, votre système proposera mieux et crypt le prendra en compte sans que vous ayez à changer votre code.

    Le bonus c’est que la base de mot de passe générée sera compatible avec la plupart des applications unix, des authentifications Apache aux logins système. Vous pourrez ainsi partager et synchroniser votre base sans la stocker à plein d’endroit

  5. Eric Says:

    Argh, grillé par Hugo, mais je le soutiens.

  6. Christophe Buguet Says:

    Merci pour ces suggestions. crypt() semble en effet beaucoup plus judicieux s’il n’y a pas de contraintes d’utilisation d’un algo particulier.

    Pour sha1 et md5, il y aura certainement quelque chose de mieux puisque des failles existent déjà dans les deux algorithmes…

Leave a Reply

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in