De temps en temps, j'entends le conseil "Utiliser bcrypt pour stocker des mots de passe en PHP, règles bcrypt".
Mais c'est quoi bcrypt
? PHP n'offre pas de telles fonctions, Wikipedia babille sur un utilitaire de cryptage de fichiers et les recherches sur le Web révèlent simplement 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 chiffrement à usage général, il fonctionne de deux manières. S'il peut être chiffré, il peut être déchiffré. Les mots de passe ont besoin d'une fonction de hachage unidirectionnelle.
Quelle est l'explication?
bcrypt
un algorithme de hachage unidirectionnel par rapport à un schéma de chiffrement dans ma réponse . Il y a toute cette idée fausse quibcrypt
n'est que Blowfish alors qu'en fait, elle a un calendrier de clés totalement différent qui garantit que le texte brut ne peut pas être récupéré à partir du texte de chiffrement sans connaître l'état initial du chiffrement (sel, tours, clé).Réponses:
bcrypt
est un algorithme de hachage qui est évolutif avec du matériel (via un nombre configurable de tours). Sa lenteur et ses multiples tours garantissent qu'un attaquant doit déployer des fonds et du matériel massifs pour pouvoir casser vos mots de passe. Ajoutez à cela des sels par mot de passe (bcrypt
nécessite des sels) et vous pouvez être sûr qu'une attaque est pratiquement impossible sans une somme ridicule de fonds ou de matériel.bcrypt
utilise l' algorithme Eksblowfish pour hacher les mots de passe. Alors que la phase de chiffrement d' Eksblowfish et Blowfish sont exactement les mêmes, la phase de planification des clés d' Eksblowfish garantit que tout état ultérieur dépend à la fois du sel et de la clé (mot de passe utilisateur), et aucun état ne peut être précalculé à l'insu des deux. En raison de cette différence clé, ilbcrypt
s'agit d'un algorithme de hachage unidirectionnel. Vous ne pouvez pas récupérer le mot de passe en texte brut sans connaître le sel, les tours et la clé (mot de passe). [ Source ]Comment utiliser bcrypt:
En utilisant PHP> = 5.5-DEV
Les fonctions de hachage de mot de passe ont maintenant été intégrées directement dans PHP> = 5.5 . Vous pouvez maintenant utiliser
password_hash()
pour créer unbcrypt
hachage de n'importe quel mot de passe:Pour vérifier un mot de passe fourni par l'utilisateur par rapport à un hachage existant, vous pouvez utiliser le
password_verify()
comme tel:En utilisant PHP> = 5.3.7, <5.5-DEV (également RedHat PHP> = 5.3.3)
Il existe une bibliothèque de compatibilité sur GitHub créée sur la base du code source des fonctions ci-dessus écrites à l'origine en C, qui fournit les mêmes fonctionnalités. Une fois la bibliothèque de compatibilité installée, l'utilisation est la même que ci-dessus (moins la notation du tableau abrégé si vous êtes toujours sur la branche 5.3.x).
Utilisation de PHP <5.3.7 (obsolète)
Vous pouvez utiliser la
crypt()
fonction pour générer des hachages bcrypt de chaînes d'entrée. Cette classe peut générer automatiquement des sels et vérifier les hachages existants par rapport à une entrée. Si vous utilisez une version de PHP supérieure ou égale à 5.3.7, il est fortement recommandé d'utiliser la fonction intégrée ou la bibliothèque compat . Cette alternative n'est fournie qu'à des fins historiques.Vous pouvez utiliser ce code comme ceci:
Alternativement, vous pouvez également utiliser le framework de hachage PHP portable .
la source
mt_rand()
est également défini en utilisant l'heure actuelle et l'ID de processus actuel. Veuillez voirGENERATE_SEED()
dans/ext/standard/php_rand.h
.crypt()
est alors révisée par les pairs et vérifiée. Le code ci-dessus appelle PHPcrypt()
, qui appelle lacrypt()
fonction POSIX . Tout ce que le code ci-dessus fait de plus est de générer un sel aléatoire (qui n'a pas besoin d'être sécurisé cryptographiquement, le sel n'est pas considéré comme un secret) avant d'appelercrypt()
. Vous devriez peut-être faire vous-même quelques recherches avant d'appeler le loup.crypt()
) est soumis à une vulnérabilité de sécurité antérieure à 5.3.7, et est (très légèrement) inefficace après 5.3.7 - les détails du problème concerné peuvent être trouvés ici . Veuillez également noter que la nouvelle API de hachage de mot de passe ( compatibilité ascendante ) est désormais la méthode préférée pour implémenter le hachage de mot de passe bcrypt dans votre application.Alors, vous voulez utiliser bcrypt? Impressionnant! Cependant, comme dans d'autres domaines de la cryptographie, vous ne devriez pas le faire vous-même. Si vous devez 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 si facile de visser 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 courants.
Avouons-le, la cryptographie est difficile.
Laissez-le aux experts. Laissez-le aux personnes dont le travail consiste à entretenir ces bibliothèques. Si vous devez prendre une décision, vous vous trompez.
Utilisez plutôt une bibliothèque. Plusieurs existent selon vos besoins.
Bibliothèques
Voici une ventilation de certaines des API les plus courantes.
API PHP 5.5 - (Disponible pour 5.3.7+)
Depuis PHP 5.5, une nouvelle API de hachage des mots de passe est en cours d'introduction. Il existe également une bibliothèque de compatibilité de shim maintenue (par moi) pour 5.3.7+. Cela a l'avantage d'être une implémentation évaluée par les pairs et simple à utiliser.
Vraiment, il vise à être extrêmement simple.
Ressources:
Zend \ Crypt \ Password \ Bcrypt (5.3.2+)
Il s'agit d'une autre API similaire à celle de PHP 5.5 et remplit une fonction similaire.
Ressources:
PasswordLib
Il s'agit d'une approche légèrement différente du hachage de mot de passe. Plutôt que 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 les systèmes hérités et 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+
Références:
PHPASS
C'est une couche qui prend en charge bcrypt, mais prend également en charge un algorithme assez puissant qui est utile si vous n'avez pas accès à PHP> = 5.3.2 ... Il prend en charge PHP 3.0+ (mais pas avec bcrypt).
Ressources
Remarque: N'utilisez pas les alternatives PHPASS qui ne sont pas hébergées sur openwall, ce sont des projets différents !!!
À propos de BCrypt
Si vous remarquez, chacune de ces bibliothèques renvoie une seule chaîne. C'est à cause de la façon dont BCrypt fonctionne en interne. Et il y a des tonnes de réponses à ce sujet. Voici une sélection que j'ai écrite, que je ne copierai / collerai pas ici, mais un lien vers:
md5
mots de passe vers bcryptEmballer
Il existe de nombreux choix différents. Le choix vous appartient. 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 directementhash()
(oumd5()
ousha1()
), vous faites certainement quelque chose de mal.Utilisez simplement une bibliothèque ...
la source
mt_rand()
une période suffisamment élevée, mais la valeur de départ n'est que de 32 bits. Donc, l'utilisationmt_rand()
vous limite efficacement à seulement 32 bits d'entropie. Ce qui, grâce au problème d'anniversaire, signifie que vous avez 50% de chances de collision avec seulement 7k de sels générés (globalement). Depuisbcrypt
accepte 128 bits de sel, il est préférable d'utiliser une source qui peut fournir tous les 128 bits ;-). (à 128 bits, 50% de chances de collision se produisent lors des hachages 2e19) ...mt_rand
etuniqid
(et donclcg_value
etrand
) ne sont pas des premiers choix ...Vous obtiendrez beaucoup d'informations dans Enough With The Rainbow Tables: Ce que vous devez savoir sur les schémas de mot de passe sécurisés ou le framework 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 qui obtient votre base de données de mots de passe 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, beaucoup pour quelqu'un qui essaie de le forcer brutalement). Bcrypt est lent et peut être utilisé avec un paramètre pour choisir sa lenteur.
la source
Vous pouvez créer un hachage unidirectionnel avec bcrypt en utilisant la
crypt()
fonction PHP et en passant un sel Blowfish approprié. Le plus important de toute l'équation est que A) l'algorithme n'a pas été compromis et B) vous salez correctement chaque mot de passe . N'utilisez pas de sel pour toute l'application; qui ouvre toute votre application pour attaquer à partir d'un seul ensemble de tables Rainbow.PHP - Fonction Crypt
la source
crypt()
fonction PHP , qui prend en charge plusieurs fonctions de hachage de mot de passe différentes. Assurez-vous que vous n'utilisez pasCRYPT_STD_DES
ouCRYPT_EXT_DES
- l'un des autres types pris en charge est correct (et inclut bcrypt, sous le nomCRYPT_BLOWFISH
).crypt
expose plusieurs hachages de mot de passe, avec bcrypt correspondant à laCRYPT_BLOWFISH
constante. Bcrypt est actuellement l'algorithme le plus puissant pris en charge parcrypt
et plusieurs autres qu'il prend en charge sont assez faibles.Edit: 2013.01.15 - Si votre serveur le supporte, utilisez plutôt la solution de martinstoeckli .
Tout le monde veut rendre cela plus compliqué qu'il ne l'est. La fonction crypt () fait la plupart du travail.
Exemple:
Je sais que cela devrait être évident, mais veuillez ne pas utiliser le mot de passe comme mot de passe.
la source
2y
place de2a
.mcrypt_create_iv($size, MCRYPT_DEV_URANDOM)
comme source pour le sel.bcrypt
.mcrypt_create_iv(17, MCRYPT_DEV_URANDOM)
,str_replace('+', '.', base64_encode($rawSalt))
,$salt = substr($salt, 0, 22);
La version 5.5 de PHP aura un support intégré pour BCrypt, les fonctions
password_hash()
etpassword_verify()
. En fait, ce ne sont que des wrappers autour de la fonctioncrypt()
, et il sera plus facile de l'utiliser correctement. Il prend en charge la génération d'un sel aléatoire sûr et fournit de bonnes valeurs par défaut.La façon la plus simple d'utiliser ces fonctions sera:
Ce code hachera le mot de passe avec BCrypt (algorithme
2y
), génère un sel aléatoire à partir de la source aléatoire du système d'exploitation et utilise le paramètre de coût par défaut (actuellement 10). La deuxième ligne vérifie si le mot de passe saisi par l'utilisateur correspond à une valeur de hachage déjà stockée.Si vous souhaitez modifier le paramètre de coût, vous pouvez le faire comme ceci, en augmentant le paramètre de coût de 1, double le temps nécessaire pour calculer la valeur de hachage:
Contrairement au
"cost"
paramètre, il est préférable d'omettre le"salt"
paramètre, car la fonction fait déjà de son mieux pour créer un sel cryptographiquement sûr.Pour PHP version 5.3.7 et versions ultérieures, il existe un pack de compatibilité , du même auteur qui a créé la
password_hash()
fonction. Pour les versions PHP antérieures à 5.3.7, il n'y a pas de support pourcrypt()
with2y
, l'algorithme BCrypt sécurisé unicode. On pourrait le remplacer à la place par2a
, ce qui est la meilleure alternative pour les versions PHP antérieures.la source
Pensée actuelle: les hachages devraient être les plus lents disponibles, et non les plus rapides possibles. Cela supprime les attaques de table arc-en-ciel .
Également lié, mais par précaution: un attaquant ne devrait jamais avoir un accès illimité à votre écran de connexion. Pour éviter cela: configurez une table de suivi des adresses IP qui enregistre chaque occurrence avec l'URI. Si plus de 5 tentatives de connexion proviennent de la même adresse IP au cours d'une période de cinq minutes, bloquez avec explication. Une approche secondaire consiste à avoir un système de mot de passe à deux niveaux, comme les banques. Mettre un verrouillage pour les échecs sur la deuxième passe renforce la sécurité.
Résumé: ralentissez l'attaquant en utilisant des fonctions de hachage chronophages. De plus, bloquez trop d'accès à votre connexion et ajoutez un deuxième niveau de mot de passe.
la source
Voici une réponse mise à jour à cette vieille question!
La bonne façon de hacher les mots de passe en PHP depuis 5.5 est avec
password_hash()
, et la bonne façon de les vérifier est avecpassword_verify()
, et cela est toujours vrai en PHP 8.0. Ces fonctions utilisent des hachages bcrypt par défaut, mais d'autres algorithmes plus puissants ont été ajoutés. Vous pouvez modifier le facteur de travail (en fait, la force du cryptage) via lespassword_hash
paramètres.Cependant, bien qu'il soit encore assez fort, bcrypt n'est plus considéré comme à la pointe de la technologie ; un meilleur ensemble d'algorithmes de hachage de mot de passe est arrivé appelé Argon2 , avec les variantes Argon2i, Argon2d et Argon2id. La différence entre eux (comme décrit ici ):
Le support Argon2i a été ajouté en PHP 7.2, et vous le demandez comme ceci:
et le support Argon2id a été ajouté en PHP 7.3:
Aucune modification n'est requise pour vérifier les mots de passe car la chaîne de hachage résultante contient des informations sur l'algorithme, le sel et les facteurs de travail utilisés lors de sa création.
Tout à fait séparément (et quelque peu redondant), libsodium (ajouté en PHP 7.2) fournit également le hachage Argon2 via les fonctions
sodium_crypto_pwhash_str ()
etsodium_crypto_pwhash_str_verify()
, qui fonctionnent à peu près de la même manière que les fonctions intégrées de PHP. Une des raisons possibles de leur utilisation est que PHP peut parfois être compilé sans libargon2, ce qui rend les algorithmes Argon2 indisponibles pour la fonction password_hash; PHP 7.2 et supérieur devraient toujours avoir libsodium activé, mais ce n'est peut-être pas le cas - mais au moins il y a deux façons d'obtenir cet algorithme. Voici comment vous pouvez créer un hachage Argon2id avec libsodium (même en PHP 7.2, qui, autrement, ne prend pas en charge Argon2id)):Notez qu'il ne vous permet pas de spécifier un sel manuellement; cela fait partie de la philosophie de libsodium - ne permettez pas aux utilisateurs de définir des paramètres qui pourraient compromettre la sécurité - par exemple, rien ne vous empêche de passer une chaîne de sel vide à la
password_hash
fonction PHP ; libsodium ne vous laisse rien faire de si bête!la source
Pour les mots de passe OAuth 2 :
la source
Comme nous le savons tous, le stockage du mot de passe en texte clair dans la base de données n'est pas sécurisé. le bcrypt est une technique de hachage de mot de passe. l'une des fonctions étonnantes de bcrypt est qu'il nous protège des pirates informatiques, il est utilisé pour protéger le mot de passe contre les attaques de piratage, car le mot de passe est stocké sous forme bcryptée.
la fonction password_hash () est utilisée pour créer un nouveau hachage de mot de passe. Il utilise un algorithme de hachage fort et robuste. La fonction password_hash () est très compatible avec la fonction crypt (). Par conséquent, les hachages de mot de passe créés par crypt () peuvent être utilisés avec password_hash () et vice-versa. Les fonctions password_verify () et password_hash () se limitent aux wrappers autour de la fonction crypt () et facilitent son utilisation avec précision.
SYNTAXE
Les algorithmes suivants sont actuellement pris en charge par la fonction password_hash ():
PASSWORD_DEFAULT PASSWORD_BCRYPT PASSWORD_ARGON2I PASSWORD_ARGON2ID
Paramètres: Cette fonction accepte trois paramètres tels que mentionnés ci-dessus et décrits ci-dessous:
mot de passe : il stocke le mot de passe de l'utilisateur. algo : C'est la constante de l'algorithme de mot de passe qui est utilisée en continu tout en désignant l'algorithme à utiliser lors du hachage du mot de passe. options : Il s'agit d'un tableau associatif, qui contient les options. Si cela est supprimé et ne comprend pas, un sel aléatoire sera utilisé et l'utilisation d'un coût par défaut se produira. Valeur de retour : il renvoie le mot de passe haché en cas de succès ou False en cas d'échec.
Exemple :
Les programmes ci-dessous illustrent la fonction password_hash () en PHP:
PRODUCTION
la source