Frage:
Empfohlene Anzahl von Runden für bcrypt
Jason Smith
2012-07-14 22:51:07 UTC
view on stackexchange narkive permalink

Was ist heutzutage (Juli 2012) die empfohlene Anzahl von Verschlüsselungsrunden zum Hashing eines Passworts für eine durchschnittliche Website (nur Name, E-Mail-Adresse und Privatadresse, aber keine Kreditkarte oder medizinische Informationen)?

In Mit anderen Worten, was ist die aktuelle Fähigkeit der Community zum Knacken von bcrypt-Passwörtern? Einige bcrypt-Bibliotheken verwenden standardmäßig 12 Runden (2 ^ 12 Iterationen). Ist das der empfohlene Arbeitsfaktor? Wären 6 Runden nicht stark genug (was zufällig die Grenze für clientseitiges bcrypt-Hashing in Javascript darstellt, siehe auch Herausfordernde Herausforderung: clientseitiges Passwort-Hashing und serverseitige Passwortüberprüfung)?

Ich habe die Antwort https://security.stackexchange.com/a/3993/11197 gelesen, in der ausführlich erläutert wird, wie die verschiedenen Faktoren ausgeglichen werden können (allerdings für PBKDF2-SHA256) ). Ich suche jedoch eine tatsächliche Nummer. Eine Faustregel.

Ich mache 120.000, aber es hängt von Ihrer Bewerbung ab. Es hängt nur von Ihrer App und Ihrer CPU-Leistung ab, die Sie dafür ausgeben können. Z.B. Wenn Sie 1 Benutzer pro Sekunde anmelden und nur 2 Kerne verwenden, würden Sie meiner Meinung nach nicht mehr als 10.000 tun. Grundsätzlich müssen Sie mit dem Befehl "time" überprüfen, wie lange es dauert, und sich selbst davon überzeugen. Etwas in der Nähe der Sekunde sollte in Ordnung sein.
@Andrew: Die Geschwindigkeit meines eigenen Systems sollte nicht für die Anzahl der Iterationen führen. Es ist die aktuelle Geschwindigkeit der Brute-Forcer, die bestimmen sollte, wie viele Iterationen als sicher gelten. Daher meine Frage: Wie viele Iterationen gelten heutzutage als sicher?
@JasonSmith, Die Geschwindigkeit Ihres Systems * ist * relevant, da sie bestimmt, wie viele Iterationen Sie vernünftigerweise durchführen können, ohne Ihr System zu blockieren. Sie möchten so viele Iterationen wie möglich, denn in Wirklichkeit reicht keine Anzahl von Iterationen aus, um absolut sicher zu sein: Wir reduzieren das Risiko nur etwas, ohne es zu eliminieren. Es gibt keine realistische Anzahl von Runden, die groß genug ist, um als sicher angesehen zu werden. Wenn Sie hier eine Frage stellen, hören Sie sich bitte die Antworten an, die Sie erhalten.
@D.W. schrieb "Bitte seien Sie bereit, auf die Antworten zu hören, die Sie erhalten", sorry, wenn ich den Eindruck erweckte, pedantisch oder stur zu sein. Vielleicht haben meine Kommentare als nicht englischer Muttersprachler die falsche Botschaft vermittelt. Ich schätze alle Antworten und bemühe mich, die Gründe dafür zu verstehen.
@JasonSmith, ok, meine Schuld für Missverständnisse, sorry!
Duplizieren bei StackOverflow: [Optimaler bcrypt-Arbeitsfaktor] (http://stackoverflow.com/q/4443476/199048)
Für alle Interessierten habe ich gerade ein kleines Java CLI-Tool geschrieben, um die Leistung von bcrypt auf Servern zu testen (was offensichtlich wichtig ist, um Sicherheit, Serverlast und Antwortzeiten in Einklang zu bringen): https://github.com/cdraeger/hash-performance
Drei antworten:
Ian Boyd
2015-03-09 20:31:43 UTC
view on stackexchange narkive permalink

Kurzversion

Die Anzahl der Iterationen, die mindestens 250 ms für die Berechnung zur Verfügung stellen.

Langversion

Als BCrypt 1999 zum ersten Mal veröffentlicht wurde, wurden sie verwendet listete die Standardkostenfaktoren ihrer Implementierung auf:

  • normaler Benutzer: 6
  • Superuser: 8

Ein Verschlüsselungspreis von 6 bedeutet 64 Runden (2 6 sup> = 64).

Sie stellen außerdem fest:

Natürlich sollten die von den Menschen gewählten Kosten von Zeit zu Zeit neu bewertet werden.

  • Zum Zeitpunkt des Einsatzes 1976 Krypta kann weniger als 4 Passwörter pro Sekunde hashen. (250 ms pro Passwort)
  • 1977 konnte auf einem VAX-11/780 die Krypta (MD5) etwa 3,6 Mal pro Sekunde ausgewertet werden. (277 ms pro Passwort)

Dies gibt Ihnen einen Eindruck von den Verzögerungen, die die ursprünglichen Implementierer beim Schreiben berücksichtigt haben:

  • ~ 250 ms für normale Benutzer
  • ~ 1 Sekunde für Superuser.

Aber je länger Sie stehen können, desto besser. Bei jeder BCrypt-Implementierung, die ich gesehen habe, wurden 10 als Standardkosten verwendet. Und meine Implementierung hat das genutzt. Ich glaube, es ist Zeit für mich, die Standardkosten auf 12 zu erhöhen.

Wir haben beschlossen, nicht weniger als 250 ms pro Hash anzuvisieren.

Mein Desktop-PC ist ein Intel Core i7-2700K CPU bei 3,50 GHz. Ich habe ursprünglich am 23.01.2014 eine BCrypt-Implementierung getestet:

  23.01.2014 Intel Core i7-2700K CPU bei 3,50 GHz | Kosten | Iterationen | Dauer || ------ | ------------------- | ------------- || 8 | 256 Iterationen | 38,2 ms | <-- Minimum von BCrypt | erlaubt 9 | 512 Iterationen | 74,8 ms || 10 | 1.024 Iterationen | 152,4 ms | <-- aktueller Standard (BCRYPT_COST = 10) | 11 | 2.048 Iterationen | 296,6 ms || 12 | 4.096 Iterationen | 594,3 ms || 13 | 8.192 Iterationen | 1.169,5 ms || 14 | 16.384 Iterationen | 2.338,8 ms || 15 | 32.768 Iterationen | 4.656,0 ms |
| 16 | 65.536 Iterationen | 9.302,2 ms |  

enter image description here

Zukunftssicherheit

Anstatt eine feste Konstante zu haben, sollte dies der Fall sein ein festes Minimum .

Anstatt Ihre Passwort-Hash-Funktion zu haben, lautet:

  String HashPassword (String-Passwort) {return BCrypt.HashPassword (Passwort) , BCRYPT_DEFAULT_COST);}  

Es sollte ungefähr so ​​aussehen:

  String HashPassword (String password) {/ * Anstatt feste Standardkosten zu verwenden, führen Sie es aus Ein Mikro-Benchmark, um herauszufinden, wie schnell die CPU ist. Verwenden Sie dies, um sicherzustellen, dass die Berechnung des Hash * / Int32 costFactor = this.CalculateIdealCost () ** mindestens ** 250 ms dauert; // Verwenden Sie niemals niedrigere Kosten als die fest codierten Standardkosten, wenn (costFactor < BCRYPT_DEFAULT_COST) costFactor = BCRYPT_DEFAULT_COST; return BCrypt.HashPassword (password, costFactor);} Int32 CalculateIdealCost () {// Benchmark mit Kosten von 5 (die zweitniedrigste zulässige) Int32 cost = 5; var sw = neue Stoppuhr (); sw.Start (); this.HashPassword ("microbenchmark", Kosten); sw.Stop (); Doppelte DauerMS = sw.Elapsed.TotalMilliseconds; // Eine Erhöhung der Kosten um 1 würde die Laufzeit verdoppeln. // Steige die Kosten weiter an, bis die geschätzte Dauer mehr als 250 ms beträgt, während (durationMS < 250) {cost + = 1; DauerMS * = 2; } Rückgabekosten;}  

Und im Idealfall ist dies Teil der BCrypt-Bibliothek aller Benutzer. Anstatt sich darauf zu verlassen, dass Benutzer der Bibliothek die Kosten regelmäßig erhöhen, erhöhen sich die Kosten regelmäßig von selbst.

Toller Beitrag, obwohl ich gegen die automatische Kostenerhöhung im Laufe der Zeit empfehlen würde. Das Moore'sche Gesetz bezieht sich eher auf die Transistordichte als auf die CPU-Leistung, wobei letztere in den letzten Jahren ein eher mangelhaftes Wachstum gezeigt hat. Auch Moores Gesetz steht kurz davor, an eine Wand zu stoßen, wo wir die grundlegende Technologie ändern müssen, damit Prozessoren weiter wachsen können. Trotzdem geschickt!
@andrewb Sie haben absolut Recht, wenn Sie Moores Gesetz anwenden. Ich habe es seitdem geändert, um ein Mikrobenchmark zu erstellen (z. B. `BCrypt.HashPassword (" Benchmark ", 5);`)
Ähm. Würde das nicht auch die Kosten * reduzieren *, wenn der Server beim Ausführen des Mikrobenchmarks unter Last steht?
@JohnMorahan No; es erhöht nur die Kosten. Siehe Kommentar "// Verwenden Sie niemals niedrigere Kosten als die fest codierten Standardkosten"
Ja, aber wenn es bereits automatisch erhöht wurde, ist die Rückkehr zur fest codierten Untergrenze immer noch eine Verringerung.
@JohnMorahan Aber ich gebe die fest codierte Untergrenze nicht automatisch zurück. Es geht darum, die Kosten zu erhöhen und nicht unter die Untergrenze zu senken. Es geht nie unter die Untergrenze.
Angenommen, Ihre Untergrenze liegt bei 10, aber basierend auf dem Mikrobenchmark entscheidet HashPassword, dass auf Ihrem Server derzeit 13 besser geeignet ist. Dann werden Sie mit einem Schrägstrich versehen und jeder meldet sich an und hämmert Ihre Website sofort. Jetzt läuft die Mikrobank langsamer und berechnet, dass 11 die angemessenen Kosten sind. Es ist keine Abnahme von 10, aber es ist eine Abnahme von 13.
@JohnMorahan Sie haben recht. Wenn Sie wirklich der Meinung sind, dass 13 das Minimum sein sollte, sollten Sie die Konstante regelmäßig erhöhen (wie es die BCrypt-Spezifikation vorschreibt). In der Zwischenzeit kann dieser Benchmark-Code nur die Sicherheit erhöhen.
@IanBoyd Vielleicht ist es eine gute Möglichkeit, damit umzugehen, wenn ein erhöhter Kostenfaktor als notwendig erachtet wird. Wenn Sie dann eine signifikante Menge dieser Protokolle erhalten, aktualisieren Sie einfach Ihre bcrypt-Konfiguration auf das neue Minimum
@Cruncher Menschen werden * sooo * frech und pissig, wenn Apps versuchen, mithilfe von Telemetrie die Dinge besser zu machen.Wir müssen das Beste tun, was wir können.Die Realität ist, dass jeder Entwickler jemals * keine * Ahnung haben wird, was es bedeutet, was er dagegen tun soll, welche Risiken bestehen oder wie er vorgehen soll.* (Lasst uns ein CAB-Meeting abhalten, wir müssen alle Stakeholder einholen, was sind die Auswirkungen, was ist die Notfallwiederherstellung, wie viel Ausfallzeit) * ** `schießt sich selbst in den Kopf` **.Es wird also jahrelang nicht repariert.Der Code muss nur das Richtige tun.* (auch bekannt als "die Grube des Erfolgs") *
Ehrlich gesagt denke ich, dass dies aus praktischer Sicht wirklich eine gute Idee ist und vielleicht die besten Anstrengungen zur Zukunftssicherung.In Bezug auf die Verringerung der gleichzeitigen Auslastung (dh verzerrte Ergebnisse) können Sie nur [Überarbeitung der Init / Laufzeitkonfiguration der Anwendung] in Betracht ziehen (https://docs.microsoft.com/en-us/dotnet/api/system.configuration.configuration).Speichern Sie? view = dotnet-plat-ext-3.1) oder pflegen Sie es in einer nahe gelegenen Cache-Datei (aber halten Sie trotzdem ein festes Inline-Minimum fest, falls etwas mit dieser Datei passiert), wobei neue / höhere Arbeitsfaktorwerte entdeckt werden, die zuvor verworfen wurdenerreichte Benchmarks.
@MattBorja Das sind alles gute Ideen;aber abhängig von der spezifischen Umgebung.Dieselbe Bibliotheksklasse muss die Ausführung auf einem Desktop-PC als Standardbenutzer sowie als Dienst mit den geringsten Berechtigungen sowie auf Azure ohne Dateisystem, INI-Datei, `.config` oder Registrierung unterstützen.Sicherlich kann die Bcrypt-Bibliothek ein öffentliches "BCrypt.GetIdealCost ()" verfügbar machen und den Entwickler entscheiden lassen, wann und wie oft es aktualisiert werden soll.Es tritt jedoch immer noch das Problem auf, dass Entwickler sich nicht damit befassen sollten.weil wir alle wissen, dass sie es einfach nicht tun.
@IanBoyd Abstraktionsebenen bestimmen, mit was Entwickler umgehen sollen / nicht, mein Freund.Wir mögen Frameworks aus dem gleichen Grund, aus dem wir Automatikgetriebe mögen: Sie übernehmen einen Großteil des Denkens für uns.Aber dann schicken wir Leute zum Training (d. H. College, Handel usw.), weil wir Leute brauchen, die auch für sich selbst denken. Für heute geht es hauptsächlich um die Aufrechterhaltung von Arbeitsfaktoren. Daher können andere praktikable, nicht dateibasierte Lösungen auch In-Memory-Caching umfassen (unabhängig davon, ob es sich um Statik, Anwendungsvariablen, Sitzung usw. handelt).Dies würde sicherlich die Plattformabhängigkeit verringern.
D.W.
2012-07-16 03:57:13 UTC
view on stackexchange narkive permalink

Ich denke, die Antwort auf alle Ihre Fragen ist bereits in Thomas Pornins Antwort enthalten. Sie haben darauf verlinkt, also wissen Sie vermutlich davon, aber ich schlage vor, dass Sie es erneut lesen.

Die Grundprinzipien sind: Wählen Sie keine Anzahl von Runden; Wählen Sie stattdessen die Zeit, die die Kennwortüberprüfung auf Ihrem Server benötigt, und berechnen Sie dann die Anzahl der Runden basierend darauf. Sie möchten, dass die Überprüfung so lange wie möglich dauert.

Einige Beispiele für konkrete Zahlen finden Sie in der Antwort von Thomas Pornin. Er schlägt vor, dass ein vernünftiges Ziel darin besteht, dass die Kennwortüberprüfung / das Hashing 241 Millisekunden pro Kennwort dauert. (Hinweis: Thomas hat anfangs "8 Millisekunden" geschrieben, was falsch ist - dies ist die Zahl für eine Geduld von einem Tag anstelle eines Monats.) Damit kann Ihr Server immer noch 4 Passwörter pro Sekunde überprüfen ( mehr, wenn Sie es parallel tun können). Thomas schätzt, dass sich, wenn dies Ihr Ziel ist, ungefähr 20.000 Runden im richtigen Stadion befinden.

Die optimale Anzahl von Runden ändert sich jedoch mit Ihrem Prozessor. Im Idealfall messen Sie, wie lange Ihr Prozessor benötigt, und wählen die Nummer entsprechend aus. Das dauert nicht so lange; Um optimale Ergebnisse zu erzielen, erstellen Sie einfach das Skript und ermitteln Sie, wie viele Runden erforderlich sind, um sicherzustellen, dass das Hashing von Kennwörtern auf Ihrem Server etwa 240 Millisekunden dauert (oder länger, wenn Sie es ertragen können).

Zeit spielt keine Rolle, Geld ist der Grund, warum sich die Welt dreht.
Es fällt mir schwer zu verstehen, warum * meine * Plattform die Anzahl der Hashing-Runden bestimmt. Eine clientseitige Javascript-bcrypt-Implementierung kann auf einem älteren mobilen Gerät ungefähr 2 ^ 6 Runden ausführen, meine neueste Hardware kann 2 ^ 13 Runden ausführen. Sie haben jedoch an anderer Stelle kommentiert, dass "12 Runden mit ziemlicher Sicherheit nicht ausreichen". Wie kann die Geschwindigkeit meiner Implementierung relevant sein? Vielleicht bedeutet dies nur, dass ich schnellere Hardware kaufen muss und keine sichere Website auf einem alten Pentium 4 betreiben kann, der 2 ^ 4 Runden macht?
Wenn 12 Runden das Beste sind, was Sie tun können, machen Sie das mit. Die zusammenfassende Version besagt, dass Sie so viele Runden verwenden möchten, wie Sie tolerieren können (für eine angemessene Anzahl von Runden ist sogar noch mehr besser). Daher ist die Geschwindigkeit Ihrer Implementierung relevant, da sie eine Obergrenze für die Anzahl der Runden festlegt, die Sie verwenden können (wenn Sie die Anzahl der Runden lächerlich groß einstellen, dauert es zu lange). Ich empfehle, die Anzahl der Runden so nahe wie möglich an dieser Obergrenze festzulegen. Deshalb ist die Geschwindigkeit Ihrer Implementierung relevant.
P.S. Ich empfehle nicht, bcrypt in Javascript zu implementieren, da die Leistung wahrscheinlich sehr schlecht sein wird. Ich gehe davon aus, dass Sie bcrypt auf dem Server berechnen. (Ich glaube nicht, dass die Berechnung von bcrypt auf dem Client einen ausreichenden Wert hat. Daher empfehle ich nicht, bcrypt auf dem Client zu berechnen.) Ich schlage vor, eine native, optimierte Implementierung von bcrypt zu verwenden. das wird viel schneller laufen.
Irgendwo sollte es eine Nummer geben. Wie viele Runden unser System tolerieren kann, ist nicht relevant. Entscheidend ist, wie schwierig es für die NSA ist, Ihr Passwort zu knacken, wenn es nur 10 Runden bcrypt durchlaufen hat (die Standardeinstellung in vielen Systemen). Und ich sage NSA, weil ich nicht glaube, dass es andere Gruppen gibt, die die gleiche Rechenleistung bieten können.
@David 天宇 Wong, die Anzahl der Runden, die unser System aushalten kann, ist * relevant *. Es gibt keine praktische Anzahl von Runden, die ausreichten, um es der NSA unmöglich zu machen, Passwörter (auch schwache) zu knacken. Sie können also niemals 100% ige Sicherheit erhalten - es ist immer ein Kompromiss zwischen der Schwierigkeit, die Sie für sich selbst haben, und der Schwierigkeit, die Sie für den Gegner haben. Angesichts der Tatsache, wie Benutzer Passwörter auswählen, können wir es dem Gegner jedoch niemals so schwer machen, wie wir es uns wirklich wünschen. Dies ist eine Risikominderung, keine Risikoliminierung.
@D.W., Ich verstehe es nicht. Jede Runde erhöht die Komplexität der Brute Force. An einem Punkt wird es für jede Maschine / Gruppe von Maschinen auf der Erde unmöglich sein, dies zu knacken, selbst die der NSA.
@David 天宇 Wong, eine nicht triviale Anzahl von Personen wählt ein schwaches Passwort (z. B. 10 Bit Entropie). Wir brauchen zum Beispiel 2 ^ 70 Iterationen, um dies gegen die NSA zu sichern. Wenn Sie 2 ^ 70 Iterationen von bcrypt durchführen würden, könnte es in der Praxis niemand verwenden, da es für die Guten viel zu langsam wäre. Aus diesem Grund gibt es keinen Wert für die Anzahl der Iterationen, die sowohl eine starke Sicherheit gegen starke Gegner (wie die NSA) bieten als auch klein genug sind, um für die legitimen Benutzer des Systems praktisch zu sein. Wie auch immer, wir sind ein bisschen weit von der gestellten Frage entfernt.
Ich habe nicht an diesen Anwendungsfall gedacht. Natürlich können Sie schwache Passwörter nie schützen, aber Sie sollten über die Anzahl der Iterationen nachdenken, um normale Passwörter zu schützen. Was meinst du mit 10 Entropiebits für ein pw? Ich denke, die Entropie des Passworts ist 2 ^ 10, aber was bedeutet das?
@David 天宇 Wong, ein Passwort mit 10 Entropiebits * ist * normal. Aber wenn Ihnen das nicht gefällt, ziehen Sie ein Passwort mit 20 Bit Entropie in Betracht. (Mehr als die Hälfte aller Benutzer hat ein Passwort mit weniger als 20 Entropiebits.) Dann benötigen Sie 2 ^ 60 Icrypt-Iterationen, um eine starke Sicherheit für diese Passwörter zu gewährleisten, aber das ist viel zu viel für die Guten. Versuchen Sie, dies selbst durchzuarbeiten. Es gibt viele Ressourcen darüber, was Entropie ist - dies ist nicht der Ort, um dies zu erklären / zu fragen. Entropie ist ein grundlegendes Konzept, das Sie verstehen müssen, um die Passwortsicherheit zu verstehen.
rook
2012-07-15 01:15:58 UTC
view on stackexchange narkive permalink

Stärkere Tastenableitung über sequentielle speicherharte Funktionen ist ein sehr gutes Papier zum Thema Tastendehnung. Auf Seite 14 werden verschiedene Hashing-Algorithmen damit verglichen, wie viel Geld es kosten wird, den Hash zu brechen. Dies ist eine nützliche Methode, um über diese Dinge nachzudenken. (Nebenbei bemerkt, ChromeOS verwendet Scrypt, wenn TPM nicht verfügbar ist.)

Sie möchten, dass diese Kennwort-Hashes so lange wie möglich nicht unterbrochen werden. Nach Moores Gesetz ist dies ein exponentiell schnelles Ziel. Scrypt verwendet eine variable Menge an Speicher und CPU. Diese Variable kann in Abhängigkeit von der Zeit schwerer werden. Jedes Mal, wenn sich der Client anmeldet, können Sie den Kennwort-Hash aktualisieren, um die Sicherheit zu erhöhen. Im Fall von PBKDF2 könnte dies wie round = 2 ^ (current_year-2000) oder so ähnlich aussehen.

Es ist wichtig zu beachten, dass Sie diese Verarbeitung nicht einfach auf den Client auslagern können und erwarten, dass Ihr Protokoll sicher ist. Bei allen mir bekannten clientseitigen Hashing-Authentifizierungsprotokollen muss der Server eine identische Berechnung durchführen, um die Authentifizierungsdaten (NTLM, NTLMv2, SRP, WPA-PSK ...) zu überprüfen.

Ich bin mir bewusst, dass ich Moores Gesetz entsprechen sollte. Aber genau das ist meine Frage: Wie viele Iterationen gelten heutzutage angesichts der aktuellen Geschwindigkeit der Brute-Forcer als sicher?
@Jason Smith Ich glaube nicht, dass Ihnen jemand eine reelle Zahl geben kann, weil dies umständlich ist. Meine Antwort war 2 ^ 12, was 4096 ist, und meine Begründung ist, weil es 2012 ist.
Ah, ich dachte 2 ^ (current_year-2000) sei nur ein willkürliches Beispiel. Ok, also 12 Runden im Jahr 2012.
Nein, 12 Runden sind mit ziemlicher Sicherheit nicht genug.
@D.W. 4096 Iterationen sind größer als die meisten Implementierungen, die ich gesehen habe. Denken Sie daran, dass es nächstes Jahr 8192 sein wird ...
@Rook, Ich bin bei dir! Ich habe nur darauf hingewiesen, dass Jason Smith über den Unterschied zwischen 12 Runden und 2 ^ 12 Runden verwirrt zu sein schien.


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...