php - password_bcrypt - password_verify




Comment utilisez-vous bcrypt pour hacher les mots de passe en PHP? (6)

De temps en temps, j'entends le conseil "Utiliser bcrypt pour stocker les mots de passe en PHP, les règles de bcrypt".

Mais qu'est-ce que bcrypt ? PHP n'offre pas de telles fonctions, Wikipedia babille sur un utilitaire de chiffrement de fichier et les recherches sur le Web révèlent juste quelques implémentations de Blowfish dans différentes langues. Maintenant, Blowfish est également disponible en PHP via mcrypt , mais comment cela aide-t-il à stocker les mots de passe? Blowfish est un chiffre universel, il fonctionne de deux façons. S'il peut être chiffré, il peut être déchiffré. Les mots de passe nécessitent une fonction de hachage unidirectionnelle.

Quelle est l'explication?


Donc, vous voulez utiliser bcrypt? Impressionnant! Cependant, comme d'autres domaines de la cryptographie, vous ne devriez pas le faire vous-même. Si vous avez besoin de vous soucier de gérer des clés, de stocker des sels ou de générer des nombres aléatoires, vous vous trompez.

La raison est simple: il est tellement facile de bousiller bcrypt . En fait, si vous regardez presque chaque morceau de code sur cette page, vous remarquerez qu'il viole au moins un de ces problèmes communs.

Face It, la cryptographie est difficile.

Laissez-le pour les experts. Laissez les gens qui travaillent pour maintenir ces bibliothèques. Si vous devez prendre une décision, vous le faites mal.

Au lieu de cela, utilisez simplement une bibliothèque. Plusieurs existent en fonction de vos besoins.

Bibliothèques

Voici une répartition de certaines des API les plus courantes.

PHP 5.5 API - (Disponible pour 5.3.7+)

Depuis PHP 5.5, une nouvelle API pour le hachage des mots de passe est en cours d'introduction. Il y a aussi une bibliothèque de compatibilité de shim maintenue (par moi) pour 5.3.7+. Cela a l'avantage d'être une mise en œuvre revue par les pairs et simple à utiliser.

function register($username, $password) {
    $hash = password_hash($password, PASSWORD_BCRYPT);
    save($username, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    if (password_verify($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Vraiment, il vise à être extrêmement simple.

Ressources:

Zend \ Crypt \ Mot de passe \ Bcrypt (5.3.2+)

C'est une autre API similaire à celle de PHP 5.5, et elle a un but similaire.

function register($username, $password) {
    $bcrypt = new Zend\Crypt\Password\Bcrypt();
    $hash = $bcrypt->create($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $bcrypt = new Zend\Crypt\Password\Bcrypt();
    if ($bcrypt->verify($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Ressources:

PasswordLib

C'est une approche légèrement différente de hachage de mot de passe. Au lieu de simplement prendre en charge bcrypt, PasswordLib prend en charge un grand nombre d'algorithmes de hachage. Il est principalement utile dans les contextes où vous devez prendre en charge la compatibilité avec des systèmes hérités et disparates qui peuvent être hors de votre contrôle. Il supporte un grand nombre d'algorithmes de hachage. Et est soutenu 5.3.2+

function register($username, $password) {
    $lib = new PasswordLib\PasswordLib();
    $hash = $lib->createPasswordHash($password, '$2y$', array('cost' => 12));
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $lib = new PasswordLib\PasswordLib();
    if ($lib->verifyPasswordHash($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Les références:

  • Code source / documentation: GitHub

PHPASS

C'est une couche qui supporte bcrypt, mais supporte aussi un algorithme assez fort qui est utile si vous n'avez pas accès à PHP> = 5.3.2 ... Il supporte en fait PHP 3.0+ (mais pas avec bcrypt).

function register($username, $password) {
    $phpass = new PasswordHash(12, false);
    $hash = $phpass->HashPassword($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $phpass = new PasswordHash(12, false);
    if ($phpass->CheckPassword($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Ressources

Note: N'utilisez pas les alternatives PHPASS qui ne sont pas hébergées sur openwall, ce sont des projets différents !!!

À propos de la Colombie-Britannique

Si vous remarquez, chacune de ces bibliothèques renvoie une seule chaîne. C'est à cause de comment BCrypt fonctionne en interne. Et il y a une tonne de réponses à ce sujet. Voici une sélection que j'ai écrite, que je ne vais pas copier / coller ici, mais un lien vers:

Emballer

Il y a beaucoup de choix différents. Ce que vous choisissez est à vous. Cependant, je vous recommande fortement d'utiliser l'une des bibliothèques ci-dessus pour gérer cela pour vous.

Encore une fois, si vous utilisez crypt() directement, vous faites probablement quelque chose de mal. Si votre code utilise directement hash() (ou md5() ou sha1() ), vous vous trompez définitivement.

Utilisez simplement une bibliothèque ...


Edit: 2013.01.15 - Si votre serveur le supporte, utilisez plutôt la solution de martinstoeckli .

Tout le monde veut rendre cela plus compliqué que ça. La fonction crypt () fait la plupart du travail.

function blowfishCrypt($password,$cost)
{
    $chars='./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $salt=sprintf('$2y$%02d$',$cost);
//For PHP < PHP 5.3.7 use this instead
//    $salt=sprintf('$2a$%02d$',$cost);
    //Create a 22 character salt -edit- 2013.01.15 - replaced rand with mt_rand
    mt_srand();
    for($i=0;$i<22;$i++) $salt.=$chars[mt_rand(0,63)];
    return crypt($password,$salt);
}

Exemple:

$hash=blowfishCrypt('password',10); //This creates the hash
$hash=blowfishCrypt('password',12); //This creates a more secure hash
if(crypt('password',$hash)==$hash){ /*ok*/ } //This checks a password

Je sais que cela devrait être évident, mais s'il vous plaît, n'utilisez pas le mot de passe comme mot de passe.


Pensée actuelle: les hachages devraient être les plus lents disponibles, pas les plus rapides possibles. Cela supprime les attaques de la table arc-en-ciel .

Également lié, mais de précaution: Un attaquant ne devrait jamais avoir un accès illimité à votre écran de connexion. Pour éviter cela: Configurez une table de suivi d'adresse IP qui enregistre chaque hit avec l'URI. Si plus de 5 tentatives de connexion proviennent de la même adresse IP sur une période de cinq minutes, bloquez avec une explication. Une approche secondaire est d'avoir un schéma de mot de passe à deux niveaux, comme le font les banques. Mettre un lock-out pour les échecs sur le second passage augmente la sécurité.

Résumé: ralentir l'attaquant en utilisant des fonctions de hachage qui prennent du temps. En outre, bloquez trop d'accès à votre connexion et ajoutez un deuxième niveau de mot de passe.


Pour les mots de passe OAuth 2 :

$bcrypt = new \Zend\Crypt\Password\Bcrypt;
$bcrypt->create("youpasswordhere", 10)

Vous obtiendrez beaucoup d'informations dans Assez avec les tables arc-en-ciel: Ce que vous devez savoir sur les schémas de mot de passe sécurisé ou cadre de hachage de mot de passe PHP portable .

Le but est de hacher le mot de passe avec quelque chose de lent, donc quelqu'un obtenant votre base de données mourra en essayant de le forcer brutalement (un délai de 10 ms pour vérifier un mot de passe n'est rien pour vous). Bcrypt est lent et peut être utilisé avec un paramètre pour choisir à quel point il est lent.


Vous pouvez créer un hachage unidirectionnel avec bcrypt en utilisant la fonction crypt() de PHP et en passant un salt Blowfish approprié. Le plus important de l'équation entière est que A) l'algorithme n'a pas été compromis et B) vous saliez correctement chaque mot de passe . N'utilisez pas de sel à l'échelle de l'application; cela ouvre votre application entière pour attaquer à partir d'un seul ensemble de tables Rainbow.

PHP - Fonction de cryptage





bcrypt