La semaine dernière, j'ai lu beaucoup d'articles sur le hachage de mot de passe et Blowfish semble être (l'un des) meilleur algorithme de hachage du moment - mais ce n'est pas le sujet de cette question!
La limite de 72 caractères
Blowfish ne prend en compte que les 72 premiers caractères du mot de passe saisi:
<?php
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$hash = password_hash($password, PASSWORD_BCRYPT);
var_dump($password);
$input = substr($password, 0, 72);
var_dump($input);
var_dump(password_verify($input, $hash));
?>
La sortie est:
string(119) "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)"
string(72) "Wow. This is a super secret and super, super long password. Let's add so"
bool(true)
Comme vous pouvez le voir, seuls les 72 premiers caractères comptent. Twitter utilise blowfish aka bcrypt pour stocker leurs mots de passe ( https://shouldichangemypassword.com/twitter-hacked.php ) et devinez quoi: changez votre mot de passe Twitter en un mot de passe long de plus de 72 caractères et vous pouvez vous connecter à votre compte en saisir uniquement les 72 premiers caractères.
Blowfish et poivre
Il y a beaucoup d'opinions différentes sur les mots de passe "peppering". Certaines personnes disent que ce n'est pas nécessaire, car vous devez supposer que la chaîne de poivre secrète est également connue / publiée afin qu'elle n'améliore pas le hachage. J'ai un serveur de base de données séparé, il est donc fort possible que seule la base de données soit divulguée et non le poivre constant.
Dans ce cas (pas de fuite de poivre) vous faites une attaque basée sur un dictionnaire plus difficile (corrigez-moi si ce n'est pas juste). Si votre ficelle de poivre fuit également: pas si mal - vous avez toujours le sel et il est aussi bien protégé qu'un hasch sans poivre.
Donc, je pense que pepping le mot de passe n'est au moins pas un mauvais choix.
Suggestion
Ma suggestion pour obtenir un hachage Blowfish pour un mot de passe de plus de 72 caractères (et poivre) est:
<?php
$pepper = "foIwUVmkKGrGucNJMOkxkvcQ79iPNzP5OKlbIdGPCMTjJcDYnR";
// Generate Hash
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$password_peppered = hash_hmac('sha256', $password, $pepper);
$hash = password_hash($password_peppered, PASSWORD_BCRYPT);
// Check
$input = substr($password, 0, 72);
$input_peppered = hash_hmac('sha256', $input, $pepper);
var_dump(password_verify($input_peppered, $hash));
?>
Ceci est basé sur cette question : password_verify
retour false
.
La question
Quelle est la manière la plus sûre? Obtenir d'abord un hachage SHA-256 (qui renvoie 64 caractères) ou ne prendre en compte que les 72 premiers caractères du mot de passe?
Avantages
- L'utilisateur ne peut pas se connecter en entrant uniquement les 72 premiers caractères
- Vous pouvez ajouter le poivre sans dépasser la limite de caractères
- La sortie de hash_hmac aurait probablement plus d'entropie que le mot de passe lui-même
- Le mot de passe est haché par deux fonctions différentes
Les inconvénients
- Seuls 64 caractères sont utilisés pour créer le hachage Blowfish
Edit 1: Cette question ne concerne que l'intégration PHP de blowfish / bcrypt. Merci pour les commentaires!
Réponses:
Le problème ici est essentiellement un problème d'entropie. Alors commençons à y regarder:
Entropie par caractère
Le nombre de bits d'entropie par octet est:
Donc, comment nous agissons dépend du type de personnages que nous attendons.
Le premier problème
Le premier problème avec votre code est que votre étape de hachage "pepper" génère des caractères hexadécimaux (puisque le quatrième paramètre
hash_hmac()
n'est pas défini).Par conséquent, en hachant votre poivre, vous coupez efficacement l'entropie maximale disponible pour le mot de passe par un facteur de 2 (de 576 à 288 bits possibles ).
Le deuxième problème
Cependant,
sha256
ne fournit que des256
bits d'entropie en premier lieu. Vous réduisez donc efficacement 576 bits à 256 bits. Votre étape de hachage * immédiatement *, par définition, perd au moins 50% de l' entropie possible dans le mot de passe.Vous pouvez partiellement résoudre ce problème en passant à
SHA512
, où vous ne réduisez l'entropie disponible que d'environ 12%. Mais c'est toujours une différence non négligeable. Ces 12% réduisent le nombre de permutations d'un facteur de1.8e19
. C'est un grand nombre ... Et c'est le facteur qui le réduit de ...Le problème sous-jacent
Le problème sous-jacent est qu'il existe trois types de mots de passe de plus de 72 caractères. L'impact de ce système de style sur eux sera très différent:
Remarque: à partir de maintenant, je suppose que nous comparons à un système de poivre qui utilise
SHA512
une sortie brute (non hexadécimale).Mots de passe aléatoires à haute entropie
Ce sont vos utilisateurs qui utilisent des générateurs de mots de passe qui génèrent quel montant en grandes clés pour les mots de passe. Ils sont aléatoires (générés, non choisis par l'homme) et ont une entropie élevée par caractère. Ces types utilisent des octets élevés (caractères> 127) et certains caractères de contrôle.
Pour ce groupe, votre fonction de hachage réduira considérablement leur entropie disponible dans
bcrypt
.Permettez-moi de le répéter. Pour les utilisateurs qui utilisent des mots de passe longs et à forte entropie, votre solution réduit considérablement la force de leur mot de passe d'une quantité mesurable. (62 bits d'entropie perdus pour un mot de passe de 72 caractères, et plus pour des mots de passe plus longs)
Mots de passe aléatoires à entropie moyenne
Ce groupe utilise des mots de passe contenant des symboles courants, mais pas d'octets de poids fort ni de caractères de contrôle. Ce sont vos mots de passe à saisir.
Pour ce groupe, vous allez débloquer légèrement plus d'entropie (ne pas le créer, mais permettre à plus d'entropie de s'insérer dans le mot de passe bcrypt). Quand je dis légèrement, je veux dire légèrement. Le seuil de rentabilité se produit lorsque vous maximisez les 512 bits de SHA512. Par conséquent, le pic est à 78 caractères.
Permettez-moi de le répéter. Pour cette classe de mots de passe, vous ne pouvez stocker que 6 caractères supplémentaires avant de manquer d'entropie.
Mots de passe non aléatoires à faible entropie
Il s'agit du groupe qui utilise des caractères alphanumériques qui ne sont probablement pas générés aléatoirement. Quelque chose comme une citation biblique ou autre. Ces phrases ont environ 2,3 bits d'entropie par caractère.
Pour ce groupe, vous pouvez déverrouiller considérablement plus d'entropie (pas le créer, mais permettre à plus de tenir dans l'entrée du mot de passe bcrypt) par hachage. Le seuil de rentabilité est d'environ 223 caractères avant de manquer d'entropie.
Disons cela encore. Pour cette classe de mots de passe, le pré-hachage augmente nettement la sécurité.
Retour au monde réel
Ces types de calculs d'entropie n'ont pas vraiment beaucoup d'importance dans le monde réel. Ce qui compte, c'est de deviner l'entropie. C'est ce qui affecte directement ce que les attaquants peuvent faire. C'est ce que vous voulez maximiser.
Bien que peu de recherches aient été menées pour deviner l'entropie, je voudrais souligner certains points.
Les chances de deviner au hasard 72 caractères corrects d'affilée sont extrêmement faibles. Vous êtes plus susceptible de gagner à la loterie Powerball 21 fois que d'avoir cette collision ... C'est le nombre dont nous parlons.
Mais nous ne pouvons pas tomber dessus statistiquement. Dans le cas de phrases, la probabilité que les 72 premiers caractères soient identiques est bien plus élevée que pour un mot de passe aléatoire. Mais c'est toujours trivialement bas (vous êtes plus susceptible de gagner à la loterie Powerball 5 fois, sur la base de 2,3 bits par caractère).
Pratiquement
Pratiquement, cela n'a pas vraiment d'importance. Les chances que quelqu'un devine correctement les 72 premiers caractères, là où ces derniers font une différence significative, sont si faibles qu'il ne vaut pas la peine de s'inquiéter. Pourquoi?
Eh bien, disons que vous prenez une phrase. Si la personne parvient à bien comprendre les 72 premiers caractères, elle est soit vraiment chanceuse (peu probable), soit c'est une phrase courante. S'il s'agit d'une phrase courante, la seule variable est la durée de la création.
Prenons un exemple. Prenons une citation de la Bible (simplement parce que c'est une source courante de texte long, pas pour une autre raison):
Cela fait 180 caractères. Le 73e caractère est
g
le deuxièmeneighbor's
. Si vous avez deviné cela, vous ne vous arrêterez probablement pasnei
, mais continuez avec le reste du verset (puisque c'est ainsi que le mot de passe est susceptible d'être utilisé). Par conséquent, votre "hachage" n'a pas ajouté grand-chose.BTW: Je ne préconise ABSOLUMENT PAS l'utilisation d'une citation biblique. En fait, c'est exactement le contraire.
Conclusion
Vous n'allez pas vraiment aider les gens qui utilisent des mots de passe longs en hachant d'abord. Vous pouvez certainement aider certains groupes. Certains peuvent certainement blesser.
Mais en fin de compte, rien de tout cela n'est trop important. Les chiffres que nous traitons sont juste MANIÈRE trop élevé. La différence d'entropie ne sera pas beaucoup.
Vous feriez mieux de laisser bcrypt tel quel. Vous êtes plus susceptible de bousiller le hachage (littéralement, vous l'avez déjà fait, et vous n'êtes pas le premier ou le dernier à faire cette erreur) que l'attaque que vous essayez d'empêcher va se produire.
Concentrez-vous sur la sécurisation du reste du site. Et ajoutez un compteur d'entropie de mot de passe à la boîte de mot de passe lors de l'enregistrement pour indiquer la force du mot de passe (et indiquer si un mot de passe est trop long que l'utilisateur peut souhaiter le changer) ...
C'est mon 0,02 $ au moins (ou peut-être bien plus de 0,02 $) ...
En ce qui concerne l'utilisation d'un poivre «secret»:
Il n'y a littéralement aucune recherche sur l'alimentation d'une fonction de hachage dans bcrypt. Par conséquent, il n'est pas clair, au mieux, si l'introduction d'un hachage «poivré» dans bcrypt causera un jour des vulnérabilités inconnues (nous savons que cela
hash1(hash2($value))
peut exposer des vulnérabilités importantes autour de la résistance aux collisions et des attaques de pré-image).Étant donné que vous envisagez déjà de stocker une clé secrète (le «poivre»), pourquoi ne pas l'utiliser d'une manière bien étudiée et comprise? Pourquoi ne pas crypter le hachage avant de le stocker?
Fondamentalement, après avoir haché le mot de passe, insérez l'intégralité de la sortie de hachage dans un algorithme de chiffrement fort. Puis stockez le résultat chiffré.
Désormais, une attaque SQL-Injection ne divulguera rien d'utile, car ils n'ont pas la clé de chiffrement. Et si la clé est divulguée, les attaquants ne sont pas mieux lotis que si vous utilisiez un simple hachage (ce qui est prouvable, quelque chose avec le poivre "pré-hachage" ne fournit pas).
Remarque: si vous choisissez de faire cela, utilisez une bibliothèque. Pour PHP, je recommande fortement le
Zend\Crypt
package de Zend Framework 2 . C'est en fait le seul que je recommande à l'heure actuelle. Il a été fortement revu, et il prend toutes les décisions pour vous (ce qui est une très bonne chose) ...Quelque chose comme:
Et c'est avantageux parce que vous utilisez tous les algorithmes de manière bien comprise et bien étudiée (au moins relativement). Rappelles toi:
la source
Les mots de passe poivrants sont certainement une bonne chose à faire, mais voyons pourquoi.
Nous devons d'abord répondre à la question de savoir quand exactement un poivre aide. Le poivre ne protège que les mots de passe, tant qu'il reste secret, donc si un attaquant a accès au serveur lui-même, il ne sert à rien. Une attaque beaucoup plus simple est l'injection SQL, qui permet un accès en lecture à la base de données (à nos valeurs de hachage), j'ai préparé une démo d'injection SQL pour montrer à quel point cela peut être facile (cliquez sur la flèche suivante pour obtenir un contribution).
Alors qu'est-ce que le poivre aide réellement? Tant que le poivre reste secret, il protège les mots de passe faibles d'une attaque par dictionnaire. Le mot de passe
1234
deviendrait alors quelque chose comme1234-p*deDIUZeRweretWy+.O
. Ce mot de passe n'est pas seulement beaucoup plus long, il contient également des caractères spéciaux et ne fera jamais partie d'aucun dictionnaire.Maintenant, nous pouvons estimer les mots de passe que nos utilisateurs utiliseront, probablement plus d'utilisateurs entreront des mots de passe faibles, car il y a des utilisateurs avec des mots de passe entre 64 et 72 caractères (en fait, ce sera très rare).
Un autre point est la portée du forçage brutal. La fonction de hachage sha256 renverra une sortie de 256 bits ou des combinaisons 1.2E77, c'est beaucoup trop pour le forçage brutal, même pour les GPU (si je calculais correctement, cela prendrait environ 2E61 ans sur un GPU en 2013). On n'obtient donc pas de réel inconvénient en appliquant le poivre. Parce que les valeurs de hachage ne sont pas systématiques, vous ne pouvez pas accélérer le forçage brutal avec des modèles communs.
PS Pour autant que je sache, la limite de 72 caractères est spécifique à l'algorithme de BCrypt lui-même. La meilleure réponse que j'ai trouvée est la suivante .
PPS Je pense que votre exemple est imparfait, vous ne pouvez pas générer le hachage avec la longueur totale du mot de passe et le vérifier avec un tronçon. Vous vouliez probablement appliquer le poivre de la même manière pour générer le hachage et pour vérifier le hachage.
la source
true
. C'est le sujet de cette question. Regardez vous-même: viper-7.com/RLKFnBBcrypt utilise un algorithme basé sur l'algorithme coûteux de configuration de clé Blowfish.
La limite de mot de passe de 56 octets recommandée (y compris l'octet de terminaison nul) pour bcrypt se rapporte à la limite de 448 bits de la clé Blowfish. Les octets au-delà de cette limite ne sont pas entièrement mélangés dans le hachage résultant. La limite absolue de 72 octets sur les mots de passe bcrypt est donc moins pertinente, si l'on considère l'effet réel sur le hachage résultant de ces octets.
Si vous pensez que vos utilisateurs choisiraient normalement des mots de passe de plus de 55 octets de longueur, rappelez-vous que vous pouvez toujours augmenter les cycles d'étirement des mots de passe à la place, pour augmenter la sécurité en cas de violation de la table des mots de passe (bien que cela doive être beaucoup par rapport à l'ajout de personnages). Si les droits d'accès des utilisateurs sont si critiques que les utilisateurs auraient normalement besoin d'un mot de passe massivement long, l'expiration du mot de passe devrait également être courte, comme 2 semaines. Cela signifie qu'un mot de passe a beaucoup moins de chances de rester valide tandis qu'un pirate informatique investit ses ressources pour vaincre le facteur de travail impliqué dans le test de chaque mot de passe d'essai pour voir s'il produira un hachage correspondant.
Bien sûr, dans le cas où la table des mots de passe n'est pas violée, nous ne devrions permettre aux pirates, au maximum, que dix tentatives pour deviner le mot de passe de 55 octets d'un utilisateur, avant de verrouiller le compte de l'utilisateur;)
Si vous décidez de pré-hacher un mot de passe de plus de 55 octets, vous devez utiliser SHA-384, car il a la plus grande sortie sans dépasser la limite.
la source