Je suis curieux de savoir si quelqu'un a des conseils ou des points de référence lorsqu'il s'agit de déterminer combien d'itérations sont "assez bonnes" lors de l'utilisation de PBKDF2 (en particulier avec SHA-256). Certes, `` assez bien '' est subjectif et difficile à définir, varie selon l'application et le profil de risque, et ce qui est `` assez bien '' aujourd'hui n'est probablement pas `` assez bon '' demain ...
Mais la question demeure, qu'est-ce que l'industrie pense actuellement "assez bon"? Quels points de référence sont disponibles pour comparaison?
Quelques références que j'ai trouvées:
J'apprécierais toute référence ou commentaire supplémentaire sur la façon dont vous avez déterminé combien d'itérations étaient "assez bonnes" pour votre application.
Comme arrière-plan supplémentaire, je considère PBKDF2-SHA256 comme la méthode utilisée pour hacher les mots de passe des utilisateurs pour le stockage d'un site Web soucieux de la sécurité. Mon sel PBKDF2 prévu est: un sel aléatoire par utilisateur (stocké en clair avec chaque enregistrement d'utilisateur) XOR 'avec un sel global. L'objectif est d'augmenter le coût du forçage brut des mots de passe et d'éviter de révéler des paires d'utilisateurs avec des mots de passe identiques.
Références:
Vous devez utiliser le nombre maximal de tours qui est tolérable, en termes de performances, dans votre application. Le nombre de tours est un facteur de ralentissement, que vous utilisez sur la base que dans des conditions normales d'utilisation, un tel ralentissement a un impact négligeable pour vous (l'utilisateur ne le verra pas, le coût supplémentaire du CPU n'implique pas l'achat d'un plus grand serveur, et bientôt). Cela dépend fortement du contexte opérationnel: quelles machines sont impliquées, combien d'authentifications utilisateur par seconde ... donc il n'y a pas de réponse unique.
L'image large va ainsi:
Votre objectif est de faire en sorte que le coût moyen de briser un seul mot de passe dépasse la patience de l'attaquant, afin qu'il n'essaye même pas et continue de se concentrer sur une autre cible plus facile. Avec les notations détaillées ci-dessus, cela signifie que vous souhaitez:
v · 2n-1 > f · p
p est hors de votre contrôle; elle peut être estimée par rapport à la valeur des données et systèmes protégés par les mots de passe des utilisateurs. Disons que p est un mois (si cela prend plus d'un mois, l'attaquant ne prendra pas la peine d'essayer). Vous pouvez réduire f en achetant un serveur plus grand; d'autre part, l'attaquant tentera de rendre f plus gros en achetant de plus grosses machines. Un point aggravant est que le craquage de mot de passe est une tâche parallèle embarrassant , donc l'attaquant obtiendra un gros coup de pouce en utilisant un GPU qui prend en charge la programmation générale ; donc un f typique variera toujours de l'ordre de quelques centaines.
n se rapporte à la qualité des mots de passe, que vous pouvez influencer d'une manière ou d'une autre grâce à une politique stricte de sélection des mots de passe, mais en réalité, vous aurez du mal à obtenir une valeur de n au-delà de, disons, 32 bits. Si vous essayez d'appliquer des mots de passe plus forts, les utilisateurs commenceront à vous combattre activement, avec des solutions de contournement telles que la réutilisation de mots de passe d'ailleurs, l'écriture de mots de passe sur des notes autocollantes, etc.
Le paramètre restant est donc v. Avec f = 200 (un attaquant avec une douzaine de bons GPU), une patience d'un mois, et n = 32, vous avez besoin de v pour être d'au moins 241 millisecondes (note: j'ai initialement écrit "8 millisecondes" ici, ce qui est faux - c'est le chiffre pour une patience d'un jour au lieu d'un mois). Vous devez donc définir le nombre de tours dans PBKDF2 de sorte que le calcul sur un seul mot de passe prenne au moins autant de temps sur votre serveur. Vous pourrez toujours vérifier quatre mots de passe par seconde avec un seul cœur, donc l'impact du processeur est probablement négligeable (*). En fait, il est plus sûr d'utiliser plus de tours que cela, car, avouons-le, obtenir 32 bits d'entropie du mot de passe utilisateur moyen est un peu optimiste; d'autre part, peu d'attaques consacreront des dizaines de PC pendant un mois complet à la tâche de déchiffrer un seul mot de passe, donc peut-être qu'une "patience d'attaquant" d'un jour est plus réaliste, conduisant à un coût de vérification de mot de passe de 8 millisecondes.
Vous devez donc faire quelques repères. En outre, ce qui précède fonctionne tant que votre implémentation PBKDF2/SHA-256 est rapide. Par exemple, si vous utilisez une implémentation entièrement basée sur C #/Java, vous obtiendrez le facteur de ralentissement 2 à 3 typique (par rapport à C ou Assembly) pour les tâches gourmandes en CPU; dans les notations ci-dessus, cela équivaut à multiplier f par 2 ou 3. À titre de référence de comparaison, un processeur Core2 2,4 GHz peut effectuer environ 2,3 millions de calculs élémentaires SHA-256 par seconde (avec un seul cœur), ce qui impliquerait, sur ce processeur, environ 20000 tours pour atteindre l'objectif de "8 millisecondes".
(*) Veillez à ce que rendre la vérification des mots de passe plus coûteuse rend également votre serveur plus vulnérable aux attaques par déni de service . Vous devez appliquer certaines contre-mesures de base, telles que la mise en liste noire temporaire des adresses IP des clients qui envoient trop de demandes par seconde. Vous devez quand même le faire pour contrer les attaques de dictionnaire en ligne.
Courir openssl speed
sur la ligne de commande pour avoir une idée de la rapidité des fonctions de résumé des messages. Je peux calculer environ 1,6 million de hachages sha256 par seconde ou environ 145 milliards suppositions par jour sur mon quad core 2,2 GHz Sandy Bridge. Si quelqu'un a un mot de passe qui se trouve dans le dictionnaire anglais et a utilisé un tour de sha256, il faudrait plus de temps pour charger la liste Word du disque que pour parcourir la liste pour briser le hachage. Si vous faisiez PKBDF2-SHA256 avec quelques centaines de milliers de tours, cela prendrait quelques minutes pour se casser. L'application d'une politique de mot de passe solide aide, beaucoup.
La vraie réponse: combien de temps avez-vous à brûler?
La réponse de Thomas fournit un modèle de référence et des données utiles. Mais l'objectif qu'il pose n'a pas de sens pour moi. Un attaquant typique ne connaîtra votre nombre d'itérations qu'après avoir réellement piraté le site et saisi la base de données de hachages. Cela fait, ils ne continueront pas simplement parce que vous utilisez un grand nombre d'itérations. Ils essaieront de casser le plus grand nombre possible et feront probablement connaître les hachages afin que d'autres continuent d'essayer de les casser pendant des années avec un matériel de plus en plus puissant. Ainsi, "p" et "f" continueront tous deux d'augmenter longtemps après le hack.
De plus, les vrais mots de passe utilisateur ne sont pas bien modélisés par une mesure de complexité comme 32 bits d'entropie. L'article Sécurité réutilisable: nouveau document sur les mesures de sécurité des mots de passe est utile à cet égard et documente ce que nous savons depuis longtemps: de nombreux utilisateurs choisissent des mots de passe faciles à deviner et la queue est longue. Cela signifie également que les attaquants en trouveront toujours s'ils essaient assez fort.
Je dirais qu'un objectif plus probable serait de protéger le plus grand pourcentage possible de vos utilisateurs contre le piratage de leurs mots de passe. Par exemple. le tableau 4.2.1 du PDF montre que si vous avez réussi à limiter votre attaquant au cours d'une campagne d'attaque d'une moyenne de 1 million de tentatives par hachage à 500 000 tentatives , vous pouvez protéger les mots de passe de 5% de vos utilisateurs (en supposant un mélange avec plus de mots de passe à 7 caractères que les mots de passe à 8+ caractères, réduisant ainsi le pourcentage de craquage de 35% à 30%). Bien sûr, la forme exacte de la courbe et son emplacement varient considérablement.
Je choisirais donc le nombre d'itérations maximum que vous pouvez budgéter, tant qu'il ne retarde pas les vrais utilisateurs à se connecter normalement. Et vous devez augmenter la valeur à mesure que votre capacité de calcul augmente au fil des ans.
Une machine moderne équipée de 8 GPU de génération actuelle calculera de l'ordre de 9 milliards de hachages SHA-256 par seconde, soit environ 777 billions de hachages par jour, et ces GPU peuvent effectuer des attaques par dictionnaire basées sur des règles.
Prenez cela comme un très long commentaire. J'étais curieux de voir à quelle vitesse les choses fonctionnent sur mon ordinateur portable personnel (Thinkpad T460p, Intel i7-6700HQ ). Je sais que pour déchiffrer des mots de passe salés, il existe des appareils spéciaux, mais si vous avez un service Web, vous n'avez probablement pas de matériel spécial pour cela.
La valeur par défaut de werkzeug.security.generate_password_hash
actuellement (2019-06-01) est pbkdf2:sha256:150000
.
Comme vous pouvez le voir, le temps d'exécution croît linéairement avec le nombre de tours/itérations. Cela signifie que la valeur par défaut prend environ 281 ms en moyenne sur ma machine.
sha512, 1 iteration : min: 67.1μs, mean: 72.2μs, max: 310.9μs
sha512, 15000 iteration: min: 38462.8μs, mean: 40291.2μs, max: 44842.4μs
sha256, 15000 iteration: min: 27167.6μs, mean: 28118.0μs, max: 30826.0μs
sha512, 1000 iteration: min: 2636.7μs, mean: 2694.3μs, max: 3579.0μs
sha256, 1000 iteration: min: 1870.7μs, mean: 1888.8μs, max: 2477.0μs
md5, 15000 iteration: min: 21126.2μs, mean: 21864.8μs, max: 23799.3μs
sha512, 1 iteration : min: 23.4μs, mean: 26.9μs, max: 40.6μs
sha512, 1000 iteration: min: 2586.7μs, mean: 2761.1μs, max: 3120.6μs
sha256, 1000 iteration: min: 1823.3μs, mean: 1834.6μs, max: 2008.5μs
sha512, 15000 iteration: min: 38507.9μs, mean: 40210.8μs, max: 47430.3μs
sha256, 15000 iteration: min: 27257.1μs, mean: 28454.0μs, max: 31213.5μs
md5, 15000 iteration: min: 21219.9μs, mean: 21842.4μs, max: 24305.0μs