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?
Réponses
Trop de publicités?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.
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:
- Documentation: sur PHP.net
- Bibliothèque de compatibilité: sur GitHub
- PHP du RFC: sur wiki.php.net
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:
- Documentation: sur Zend
- Blog Post: Hachage De Mot De Passe Avec Zend Crypte
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
- Code: cvsweb
- Site du projet: sur OpenWall
- Un examen de l' < 5.3.0 algorithme: sur StackOverflow
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:
- La Différence fondamentale Entre le Malaxage Et d'Algorithmes de Chiffrement - ce qui explique la terminologie et quelques informations de base sur eux.
- À propos de l'inversion de hachages sans rainbow tables - Fondamentalement, pourquoi devrions-nous utiliser bcrypt, en premier lieu...
- Le stockage de bcrypt Hachages - fondamentalement, pourquoi le sel et l'algorithme inclus dans le résultat du hachage.
- Comment mettre à jour le coût de bcrypt hachages - essentiellement, la façon de choisir et ensuite de maintenir le coût de la bcrypt de hachage.
- Comment hachage des mots de passe longs avec bcrypt - d'expliquer les 72 caractères du mot de passe limite de bcrypt.
- Comment bcrypt utilise des sels de
- Les meilleures pratiques de salage et le saupoudrage des mots de passe , bref, de ne pas utiliser de "poivre"
- La migration de vieux
md5
des mots de passe pour bcrypt
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...
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.
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