1281 votes

Comment utilisez-vous bcrypt de hachage passe en PHP ?

Chaque maintenant et puis j'ai entendu les conseils "Utilisation bcrypt pour stocker les mots de passe en PHP, bcrypt règles".

Mais qu'est - bcrypt? PHP n'offre pas de telles fonctions, Wikipedia babille sur un fichier de l'utilitaire de chiffrement et de recherches sur le Web juste de dévoiler quelques implémentations de Blowfish dans différentes langues. Maintenant Blowfish est aussi disponible en PHP via mcrypt, mais comment cela vous aide à stocker les mots de passe? Blowfish est un objectif général de chiffrement, il fonctionne de deux manières. Si elle pouvait être chiffré, il peut être déchiffré. Les mots de passe besoin d'une fonction de hachage.

Quelle est l'explication?

1083voto

Andrew Moore Points 49765

bcrypt est un algorithme de hachage qui est évolutive avec le matériel (par l'intermédiaire d'un nombre configurable de tours). Sa lenteur et plusieurs tours assure que l'attaquant doit déployer d'immenses fonds et de matériel pour être en mesure de casser votre mot de passe. Ajoutez à cela par mot de passe sels (bcrypt NÉCESSITE sels) et vous pouvez être sûr qu'une attaque est pratiquement impossible sans que ce soit ridicule montant de fonds ou de matériel.

bcrypt utilise le Eksblowfish algorithme de hachage des mots de passe. Lorsque le cryptage de la phase de Eksblowfish et Blowfish sont exactement les mêmes, la clé du calendrier de la phase de Eksblowfish assure que l'état dépend à la fois du sel et de la clé (mot de passe utilisateur), et aucun etat ne peut être précalculées à l'insu des deux. En raison de cette différence essentielle, bcrypt est un algorithme de hachage. Vous ne pouvez pas récupérer le mot de passe en texte brut sans connaissant déjà le sel, de tours et de la clé (mot de passe). [Source]

Comment utiliser bcrypt:

À l'aide de PHP >= 5.5-DEV

Mot de passe les fonctions de hachage ont été construits directement dans PHP >= 5.5. Vous pouvez maintenant utiliser password_hash() créer un bcrypt de hachage de mot de passe:

<?php
// Usage 1:
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";
// $2y$10$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// For example:
// $2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

// Usage 2:
$options = array('cost' => 11);
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
// $2y$11$6DP.V0nO7YI3iSki4qog6OQI5eiO6Jnjsqg7vdnb.JgGIsxniOn4C

Pour vérifier qu'un utilisateur mot de passe fourni à l'encontre d'un hachage existantes, vous pouvez utiliser l' password_verify() en tant que tel:

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}

À l'aide de PHP >= 5.3.7, < 5.5-DEV (également RedHat PHP >= 5.3.3)

Il y a une bibliothèque de compatibilité sur GitHub créé, basé sur le code source des fonctions ci-dessus à l'origine écrit en C, qui offre la même fonctionnalité. Une fois la bibliothèque de compatibilité est installé, l'utilisation est la même que ci-dessus (moins l'abréviation notation de tableau, si vous êtes toujours à la 5.3.x succursale).

À l'aide de PHP < 5.3.7 (OBSOLÈTE)

Vous pouvez utiliser crypt() fonction pour générer bcrypt les hachages des chaînes d'entrée. Cette classe permet de générer automatiquement des sels et de vérifier les hachages à l'encontre d'une entrée. Si vous utilisez une version de PHP supérieure ou égale à 5.3.7, il est fortement recommandé que vous utilisez la fonction intégrée ou la compat bibliothèque. Cette alternative est fournie uniquement à des fins historiques.

class Bcrypt {
  private $rounds;
  public function __construct($rounds = 12) {
    if(CRYPT_BLOWFISH != 1) {
      throw new Exception("bcrypt not supported in this installation. See http://php.net/crypt");
    }

    $this->rounds = $rounds;
  }

  public function hash($input) {
    $hash = crypt($input, $this->getSalt());

    if(strlen($hash) > 13)
      return $hash;

    return false;
  }

  public function verify($input, $existingHash) {
    $hash = crypt($input, $existingHash);

    return $hash === $existingHash;
  }

  private function getSalt() {
    $salt = sprintf('$2a$%02d$', $this->rounds);

    $bytes = $this->getRandomBytes(16);

    $salt .= $this->encodeBytes($bytes);

    return $salt;
  }

  private $randomState;
  private function getRandomBytes($count) {
    $bytes = '';

    if(function_exists('openssl_random_pseudo_bytes') &&
        (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // OpenSSL is slow on Windows
      $bytes = openssl_random_pseudo_bytes($count);
    }

    if($bytes === '' && is_readable('/dev/urandom') &&
       ($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) {
      $bytes = fread($hRand, $count);
      fclose($hRand);
    }

    if(strlen($bytes) < $count) {
      $bytes = '';

      if($this->randomState === null) {
        $this->randomState = microtime();
        if(function_exists('getmypid')) {
          $this->randomState .= getmypid();
        }
      }

      for($i = 0; $i < $count; $i += 16) {
        $this->randomState = md5(microtime() . $this->randomState);

        if (PHP_VERSION >= '5') {
          $bytes .= md5($this->randomState, true);
        } else {
          $bytes .= pack('H*', md5($this->randomState));
        }
      }

      $bytes = substr($bytes, 0, $count);
    }

    return $bytes;
  }

  private function encodeBytes($input) {
    // The following is code from the PHP Password Hashing Framework
    $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    $output = '';
    $i = 0;
    do {
      $c1 = ord($input[$i++]);
      $output .= $itoa64[$c1 >> 2];
      $c1 = ($c1 & 0x03) << 4;
      if ($i >= 16) {
        $output .= $itoa64[$c1];
        break;
      }

      $c2 = ord($input[$i++]);
      $c1 |= $c2 >> 4;
      $output .= $itoa64[$c1];
      $c1 = ($c2 & 0x0f) << 2;

      $c2 = ord($input[$i++]);
      $c1 |= $c2 >> 6;
      $output .= $itoa64[$c1];
      $output .= $itoa64[$c2 & 0x3f];
    } while (1);

    return $output;
  }
}

Vous pouvez utiliser ce code comme ceci:

$bcrypt = new Bcrypt(15);

$hash = $bcrypt->hash('password');
$isGood = $bcrypt->verify('password', $hash);

Alternativement, vous pouvez également utiliser le Portable PHP Hachage Cadre.

302voto

ircmaxell Points 74865

Donc, vous voulez utiliser bcrypt? Génial! Toutefois, comme d'autres domaines de la cryptographie, vous ne devriez pas le faire vous-même. Si vous avez besoin de vous soucier de rien, comme la gestion des clés, ou le stockage de sels ou de génération de nombres aléatoires, vous le faites mal.

La raison en est simple: c'est tellement trivial à vis bcrypt. En fait, si vous regardez presque chaque morceau de code sur cette page, vous remarquerez que c'est la violation d'au moins un de ces problèmes communs.

En Face, la Cryptographie est dur.

Laisser pour les experts. Laisser pour les personnes dont le travail est de maintenir ces bibliothèques. Si vous avez besoin pour prendre une décision, vous le faites mal.

Au lieu de cela, il suffit d'utiliser une bibliothèque. Plusieurs existent en fonction de vos besoins.

Les bibliothèques

Voici un aperçu de quelques-uns des les plus courantes Api.

PHP 5.5 API (Disponible pour 5.3.7+)

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

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

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

Vraiment, il est destiné à être extrêmement simple.

Ressources:

Zend\Crypt\Mot De Passe\Bcrypt (5.3.2+)

C'est une autre API similaire à PHP 5.5, et 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. Plutôt que de simplement appuyer bcrypt, PasswordLib prend en charge un grand nombre d'algorithmes de hachage. Il est surtout utile dans des contextes où vous en avez besoin pour assurer la compatibilité avec les anciens et de systèmes disparates qui peuvent être hors de votre contrôle. Il prend en charge un grand nombre d'algorithmes de hachage. Et est pris en charge 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
    }
}

Références:

  • Le Code Source Et De La Documentation: GitHub

PHPASS

C'est une couche qui prend en charge bcrypt, mais prend également en charge une assez forte algorithme qui est utile si vous n'avez pas accès au PHP >= 5.3.2... Il supporte 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

Remarque: N'utilisez pas le PHPASS des solutions de rechange qui ne sont pas hébergés sur openwall, ils sont différents projets!!!

À Propos De BCrypt

Si vous remarquez, chacune de ces bibliothèques renvoie une chaîne unique. C'est parce que de la façon dont BCrypt fonctionne en interne. Et il y a une TONNE de réponses à ce sujet. Voici une sélection que j'ai écrit, que je ne vais pas copier/coller ici, mais le lien:

Envelopper

Il ya beaucoup de choix différents. Que vous choisissez est à vous. Cependant, je suis TRÈS vous recommandons d'utiliser l'un de ces bibliothèques pour la manipulation de ce pour vous.

Encore une fois, si vous utilisez crypt() directement, vous êtes probablement fait quelque chose de mal. Si votre code à l'aide de hash() (ou md5() ou sha1()) directement, vous êtes presque certainement fait quelque chose de mal.

Il suffit d'utiliser une bibliothèque...

47voto

Arkh Points 5804

Vous aurez beaucoup d’informations ici ou ici.

Le but est de hacher le mot de passe avec quelque chose de lent, donc quelqu'un obtenir votre base de données de mot de passe va mourir essayer de bruteforce (un delai de 10 ms pour vérifier qu'un mot de passe rien pour vous, c’est beaucoup pour quelqu'un qui essaie de bruteforce il). Bcrypt est lente et peut être utilisé avec un paramètre choisir c’est la lenteur.

36voto

coreyward Points 26109

Vous pouvez créer un hachage unidirectionnel avec bcrypt à l’aide de PHP `` fonctionner et le passage d’un sel de Blowfish approprié. The Most est l’importance de l’équation entière que A) l’algorithme n’a pas été compromise et B) vous sel correctement chaque mot de passe. N’utilisez pas un application à l’échelle de sel ; qui ouvre votre application complète de s’attaquer à un ensemble unique de Rainbow tables.

PHP - fonction Crypt

34voto

Jon Hulka Points 867
<hr>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X