Frage:
Änderung der Hash-Funktion
h9lpq0u
2012-08-27 19:01:29 UTC
view on stackexchange narkive permalink

Ich habe Benutzerkonto-Passwörter in einer Datenbank mit einer unsicheren (alten) kryptografischen Hash-Funktion gespeichert.

Was ist der beste / übliche Ansatz zum Ändern der Passwort-Hash-Funktion? Mir fallen nur zwei Ideen ein:

  1. Fordern Sie alle Benutzer auf, ihre Kennwörter bei der nächsten Anmeldung zu ändern und ihre Kennwörter mit einer neuen Funktion zu versehen, wenn sie dies tun. Dies ist aufgrund vieler Probleme (inaktive Benutzer, lange Migrationsdauer, komplizierte Implementierung ...) keine gute Option.

  2. Hash die alten Hashwerte mit der neuen Hashfunktion und re -Schreibe die Methode zum Überprüfen von Passwörtern anhand der Datenbank: newHash (salt + oldHash (salt + password))

  3. ol>

    Dieses doppelte Hashing scheint mir eine gute Idee zu sein, sowohl elegant als auch elegant einfach zu implementieren.

    Ich würde gerne wissen, ob es irgendwelche Einschränkungen gibt, die ich hier nicht bemerke. Wird dies normalerweise so gemacht oder gibt es eine andere Methode? Gibt es eine bekannte kryptografische Schwachstelle bei der Verwendung der Ausgabe einer schwachen Hash-Funktion als Eingabe einer starken Hash-Funktion?

    Wenn es eine gute Idee ist, was ist mit Salt? Wäre es in Ordnung, für beide Hash-Funktionen dasselbe Salz zu verwenden?

Zweitens ist höchstwahrscheinlich OK, es sei denn, "oldHash" ist extrem schlecht (weitaus schlimmer als md5). Einige Leute werden separate Salze empfehlen, aber ich denke nicht, dass das wirklich notwendig ist.
Können Sie posten, welche Art von Hashes Sie verwenden (alt und neu) und wie Sie das Salz erzeugen?
Alter Hash ist Unix-Krypta (DES-basiert) und neuer ist noch nicht entschieden. Salz ist für jeden Benutzer zufällig.
Ich bin mir ziemlich sicher, dass wir hier oder in Bezug auf Krypto eine doppelte Frage haben. Aber ich habe es nicht gefunden.
@CodesInChaos: Denken Sie an [Muss ich alle Hashes neu berechnen, wenn ich den Arbeitsfaktor in bcrypt ändere?] (Http://crypto.stackexchange.com/questions/3003/do-i-have-to-recompute-all- Hashes-wenn-ich-den-Arbeitsfaktor-in-bcrypt ändere)?
Wenn Sie sich über die zusätzliche Datenbankabfrage keine Sorgen machen, können Sie eine Option für den Kennwortverlauf implementieren. Sie können damit für immer Hashing-Versionen hinzufügen und auf alte Kennwörter zurücksetzen, Änderungen überwachen usw.
Schauen Sie sich auch http://en.wikipedia.org/wiki/Scrypt an. Mit massiv parallelen GPU- und FPGA-Cracking-Maschinen, die für nur ein paar hundert Dollar erhältlich sind, wird der Speicher zum Engpass und nicht zu ALU-Anweisungen.
Sechs antworten:
#1
+19
dr jimbob
2012-08-27 19:40:06 UTC
view on stackexchange narkive permalink

Persönlich würde ich wahrscheinlich sowohl implementieren, wenn neue Benutzer einen starken modernen Hash (bcrypt oder einen anderen kryptografischen Hash mit Schlüsselverstärkung) erhalten, als auch alte Benutzer, bei denen der schwache Hash um bcrypt gewickelt ist. Bevor sich Leute über zusätzliche Implementierungskomplexität beschweren, besteht die Alternative darin, neue Benutzer immer zu zwingen, einen schwachen Hash-Algorithmus zu verwenden, der um einen starken Hash-Algorithmus gewickelt ist, und das bedeutet, dass Sie das ursprüngliche Schema niemals loswerden.

Ich hätte einen dokumentierten Indikator für das Typ-Hash-Schema analog zu $ 1 $ , $ 2a $ , $ 5 $ oder $ 6 $ in crypt (Zitat aus der Crypt-Manpage):

  Wenn salt eine Zeichenfolge ist, die mit den Zeichen "$ id $" beginnt Lowed durch eine Zeichenfolge, die mit "$" abgeschlossen ist: $ id $ salt $ encrypted ... id identifiziert die verwendete Verschlüsselungsmethode und bestimmt dann, wie der Rest der Kennwortzeichenfolge interpretiert wird. Die folgenden Werte von id werden unterstützt: ID | Methode ─────────────────────────────────────────────────── ──────── 1 | MD5 2a | Blowfish (nicht in mainline glibc; in einigen | Linux-Distributionen hinzugefügt) 5 | SHA-256 (seit glibc 2.7) 6 | SHA-512 (seit glibc 2.7)  

In diesem Fall benötigen Sie drei Arten von Passwort-Hashes:

  1. Die alten schnellen schwachen Hashes
  2. Die alten schnellen, schwachen Hashes, die mit einem starken Salz um einen langsamen Hash gewickelt sind.
  3. Der neue langsame Hash.
  4. ol>

    An Tag 1 würde ich alles aus Kategorie 1 in Kategorie 2 verschieben. Neue Passwörter würden in Kategorie 3 eingefügt. Außerdem können Sie beim Anmelden von Personen sogar jeden erfolgreich authentifizierten Hash von Kategorie 2 in Kategorie 3 migrieren während sich das Klartext-Passwort im Speicher befindet. Irgendwann können Sie sogar alle Beweise / Legacy-Wartungsarbeiten des schwachen Hashing-Schemas vollständig eliminieren. (Zum Beispiel Benutzer mit Konten, die sich seit mehr als 2 Jahren nach der Änderung nicht mehr angemeldet haben, zum Zurücksetzen ihrer Kennwörter zu zwingen.)

Ich mag die Idee, Benutzer automatisch hinter die Kulissen zu migrieren, wenn sie sich anmelden. Ein großes Lob.
Was ist der Vorteil einer schrittweisen Migration? Der einzige Vorteil, den ich sehe, ist, dass ich nach einer bestimmten Zeit das alte Passwortschema "zurückziehen" kann. Aber warum muss ich das tun? Ich habe bereits die Methoden, um es zu benutzen, also stört es mich nicht.
#2
+11
Thomas Pornin
2012-08-27 20:38:12 UTC
view on stackexchange narkive permalink

Ihr Vorschlag 2 (nehmen Sie den alten Hashwert als "Passwort" für den neuen Hash) ist gut , wenn die folgenden Bedingungen alle zutreffen:

  • Die alter Hash ist ausreichend resistent gegen Vorbilder.
  • Der neue Hash verwendet alle erforderlichen Schnickschnack, um ihn als "robust" zu betrachten (dh das ist bcrypt mit vielen Runden und einem neuen zufälligen Salt für jedes Passwort, einschließlich für Passwortänderungen für einen bestimmten Benutzer.
  • Der alte Hash kann effizient genug berechnet werden, dass sich das gesamte Geschäft mit "konfigurierbarer Langsamkeit" darauf stützt Ausschließlich der neue Hash.

Beachten Sie, dass MD5, obwohl es in Bezug auf Kollisionen gründlich kaputt ist, in Bezug auf Vorbilder immer noch einigermaßen stark erscheint Interesse daran, ein Feld "Hash-Typ" in Ihre Datenbank aufzunehmen, damit Migrationen reibungslos abgewickelt werden können. Sie können beispielsweise Ihren Hash-of-Hash anwenden und dann eine Migration zu einem Kennwort-Hashing-Schema planen, das nur den neuen Hash verwendet. Kennwörter werden bei jeder Erstellung oder Änderung auf das neue Schema aktualisiert schrittweise Migration. Später (etwa in einem Jahr) können Sie ein erzwungenes Update (Benutzer muss das Kennwort bei der nächsten Anmeldung erneut eingeben) für die Kennwörter einrichten, die immer noch das alte Format verwenden.

Auch wenn Sie keine Migrationen mögen ( Wer tut das?), es erscheint nur ratsam, eine mögliche zukünftige Migration vorzusehen, wenn die damaligen Bedingungen Ihnen die Migration aufzwingen (z. B. eine verheerende kryptoanalytische Unterbrechung).

Was ist der Vorteil einer schrittweisen Migration? Der einzige Vorteil, den ich sehe, ist, dass ich nach einer bestimmten Zeit das alte Passwortschema "zurückziehen" kann. Aber warum muss ich das tun? Ich habe bereits die Methoden, um es zu benutzen, also stört es mich nicht.
@h9lpq0u Wenn festgestellt wird, dass das alte Schema in Bezug auf Vorbilder fehlerhaft ist, wird Ihr kombiniertes Kennwortschema möglicherweise unsicher.
#3
+7
Oleksi
2012-08-27 19:13:49 UTC
view on stackexchange narkive permalink

Ich würde bcrypt als neuen Hash verwenden. Andernfalls sollte Ihre Lösung zum "Einwickeln" der alten Hashes sicher sein, da Sie ein gutes Salz für bcrypt verwenden. Ich habe gesehen, dass diese Lösung einige Male gut funktioniert, wenn Systeme aktualisieren möchten, wie sie ihre Kennwörter hashen.

Vielen Dank. Warum empfehlen Sie bcrypt über SHA-2 (und bald auch SHA-3), dem NIST-Standard für kryptografischen Hash? Liegt es (nur) daran, dass bcrypt beliebig langsam gemacht werden kann?
Teilweise. Bcrypt und allgemeiner adaptive Hash-Algorithmen scheinen die derzeit vertrauenswürdige Lösung in der Branche zu sein. Ich vermute, dass Dinge wie bcrypt länger überleben werden. Beispielsweise gibt es bereits GPU-basierte Angriffe, die viele SHA-512-Hash-Passwörter gefährden können.
Das Kernproblem ist das gleiche; Diese Hash-Methoden sind für die Geschwindigkeit des Hashings gedacht, was das Gegenteil von dem ist, was Sie für eine Passwort-Hash-Methode wollen.
Danke für die Klarstellung. Ich werde das auf jeden Fall berücksichtigen.
@h9lpq0u Es gibt [nur zwei gute Möglichkeiten, ein Passwort zu hashen (vielleicht drei, wenn Sie abenteuerlustig sind)] (http://security.stackexchange.com/a/1164/1983). SHA-2 / SHA-3 sind nicht dafür ausgelegt.
bcrypt Ich glaube, es ist die einzige Hashing-Funktion, die weder von GPUs beschleunigt noch von Quantencomputern beeinträchtigt werden kann
@h9lpq0u Siehe [Empfehlen Sicherheitsexperten bcrypt zur Kennwortspeicherung?] (Http://security.stackexchange.com/q/4781/836) auf dieser Site.
@Earlz bcrypt * kann * durch GPUs beschleunigt werden, jedoch nicht durch einen Faktor, der dem herkömmlicher Funktionen nahe kommt. Die Verschlüsselung ist aufgrund der speicherintensiven Funktion sogar noch besser. GPUs verfügen möglicherweise über eine große Menge an integriertem RAM, aber die Bandbreite pro Kern beeinträchtigt die Leistung.
#4
+7
Earlz
2012-08-27 22:49:36 UTC
view on stackexchange narkive permalink

Wenn Sie sich nicht die Mühe machen möchten, die alte Hash-Funktion zu verwenden, sondern nicht alle dazu zwingen möchten, Ihr Passwort zu ändern, gibt es eine elegante Lösung.

Fügen Sie jedem Benutzerprofil eine Spalte / einen Wert hinzu. Rufen wir auf, wenn HashVersion

Wenn sich der Benutzer zum ersten Mal seit Ihrer Migration anmeldet, kann das System erkennen, dass es die alte Hash-Funktion verwendet. Wenn das vom Benutzer angegebene Passwort mit Ihrem Hash übereinstimmt, nehmen Sie das Klartext-Passwort und hashen es mit Ihrem neuen Algorithmus, wobei Sie auch Salze und dergleichen zurücksetzen. Und dann stoßen Sie HashVersion an, damit Sie wissen, dass es jetzt die neue Hash-Funktion verwendet.

Dies ist meiner Meinung nach die beste Lösung, insbesondere wenn Ihre vorherige Hash-Funktion wirklich unsicher war.

Ähnlich wie bei ThomasPornin und meinen früheren Antworten hinterlässt Ihre Lösung schwache Hashes in der Datenbank, bis sich der Benutzer als nächstes anmeldet. Dies ist nicht ideal, da die alten Hashes in der Zwischenzeit angegriffen werden könnten, falls die Hashes jemals durchgesickert sind. Angenommen, der alte Weg war "md5 (salt + pw)" und der neue Hash ist bcrypt, dann sollte h9lpq0u zuerst zu einem Schema wie "bcrypt (bcrypt_salt (log_rounds = 12), md5 (salt + pw)") wechseln. Andernfalls könnte ein Angreifer das Kennwort eines Benutzers leicht brutal erzwingen, wenn die Hashes in der Zwischenzeit (vor der nächsten Anmeldung) kompromittiert wurden, beispielsweise für ein selten verwendetes Konto.
@dr j, Ah, dann ersetzen Sie für das Beste aus beiden Welten den alten Hash-Wert durch "NewHash (old_hash_value)". Und wenn sie sich zum ersten Mal anmelden, ersetzen Sie es nur durch "NewHash (Passwort + Salt)"
Mit der Hash-Versionsnummer geben Sie dem Angreifer Informationen über die Stärke und den möglichen Typ des Algorithmus.Es gibt zwar nicht viele Informationen, aber es wäre immer noch besser, eine zufällige ID als HashingAlgorithmIdentifier zu verwenden, anstatt sie zu versionieren.
#5
+3
CodesInChaos
2012-08-27 19:09:48 UTC
view on stackexchange narkive permalink

Solange der alte Hash anständig ist (MD5 oder DES-Crypt ist in Ordnung, CRC32 nicht), ist dieser Ansatz sicher. Die Verwendung des gleichen Salzes sollte auch nicht zu Problemen führen, vorausgesetzt, das Salz ist gut genug, dh (fast) global eindeutig.

Für die äußere Hash-Funktion empfehle ich die Verwendung von scrypt, bcrypt oder PBKDF2.

#6
+1
tylerl
2012-08-28 08:13:45 UTC
view on stackexchange narkive permalink

Sie finden Dutzende von Open-Source-Anwendungen, die dieses Problem gelöst haben. Wordpress fällt mir schnell ein, aber es gibt auch andere. Sogar Microsoft Windows verwendet dieselbe Technik. Die allgemeine Lösung lautet wie folgt:

  • Die Ausgabe jeder unterstützten Hash-Funktion kann leicht entfernt werden. entweder durch Überprüfen des Ausgabeformats oder der Länge oder (geeigneter) durch Voranstellen einer Bezeichnerzeichenfolge (z. B. sha1: salt: _hash_output ____ ) oder durch Hinzufügen eines neuen Felds zu Ihrer Datenbank, um den Hash-Typ zu identifizieren.
  • Sie unterstützen weiterhin die Authentifizierung über alle zuvor verwendeten Hash-Funktionen, aber alle neuen Hashes geben nur die bevorzugte Version aus.
  • Optional, wenn ein Benutzer mit einer früheren Hash-Version authentifiziert wird wird das authentifizierte Passwort unter Verwendung des bevorzugten Algorithmus erneut gehasht und der gespeicherte Hash wird aktualisiert.
Es ist eine schlechte Idee, schwache Hashes zu behalten, bis sich der betreffende Benutzer anmeldet. IMO. Wenn dies eine typische Website ist, werden sich die meisten Benutzer nicht lange anmelden, wenn überhaupt.
@CodesInChaos Sicherheit ist immer ein Kompromiss. Wenn Sie möchten, können Sie Konten mit alten Hashes deaktivieren oder das gesamte alte Kennwort oder was auch immer Sie möchten zurücksetzen. Sie können den Hash jedoch nicht aktualisieren, ohne das Klartext-Passwort zu haben. Egal, ob Sie dies für eine gute Idee halten oder nicht, es ist das, was fast jeder tut.
Sie können die Double-Hash-Update-Technik verwenden, um die es in diesem Beitrag geht. Möglicherweise zusammen mit einer Bereinigung beim nächsten Login.
@CodesInChaos Ja - es ist eine interessante Lösung, die es interessanter macht, dass Sie diese Lösung in der Praxis nicht mehr sehen. Ich frage mich warum nicht.


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...