TL; DR - Sie können das Salz im Klartext ohne jegliche Verschleierung oder Verschlüsselung speichern, aber nicht nur an jemanden weitergeben, der es möchte.
Der Grund, warum wir Salze verwenden, besteht darin, Vorberechnungsangriffe wie Regenbogentabellen zu stoppen. Bei diesen Angriffen wird eine Datenbank mit Hashes und ihren Klartexten erstellt, sodass Hashes gesucht und sofort in Klartext umgewandelt werden können.
Zum Beispiel *:
86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 ae9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 b84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 c ... 948291f2d6da8e32b007d5270a0a5d094a455a02 ZZZZZX151bfc7ba4995bfa22c723ebe7921b6ddc6961bc ZZZZZY18f30f1ba4c62e2b460e693306b39a0de27d747c ZZZZZZ
Die meisten Tabellen enthalten auch eine Liste von gemeinsamen Passwörtern:
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8 passworde38ad214943daad1d64c102faec29de4afe9da3d password1b7a875fc1ea228b9061041b7cec4bd3c52ab3ce3 letmein5cec175b165e3d5e62c9e13ce848ef6feac81bff qwerty123
* Ich verwende hier SHA-1 als Beispiel, aber ich werde später erklären, warum dies eine schlechte Idee ist. sup>
Also, Wenn mein Passwort-Hash 9272d183efd235a6803f595e19616c348c275055
lautet, ist es äußerst einfach, ihn in einer Datenbank zu suchen. a Finden Sie heraus, dass der Klartext bacon4
ist. Anstatt ein paar Stunden damit zu verbringen, den Hash zu knacken (ok, in diesem Fall wären es ein paar Minuten auf einer anständigen GPU, aber wir werden später darüber sprechen), erhalten Sie das Ergebnis sofort
Offensichtlich ist dies schlecht für die Sicherheit! Also verwenden wir ein Salz. Ein Salt ist ein zufälliges eindeutiges Token, das mit jedem Passwort gespeichert wird. Angenommen, das Salz ist 5aP3v * 4! 1bN<x4i&3
und der Hash ist 9537340ced96de413e8534b542f38089c65edff3
. Jetzt ist Ihre Datenbank mit Passwörtern nutzlos, da niemand Regenbogentabellen hat, die diesen Hash enthalten. Es ist rechnerisch nicht möglich, Regenbogentabellen für jedes mögliche Salz zu erstellen.
Jetzt haben wir die Bösen gezwungen, die Hashes wieder zu knacken. In diesem Fall wäre es ziemlich einfach zu knacken, da ich ein schlechtes Passwort verwendet habe, aber es ist immer noch besser, als dass er es in einer Zehntelsekunde nachschlagen kann!
Nun, seit dem Ziel of the salt ist nur , um zu verhindern, dass vorgenerierte Datenbanken erstellt werden. Es muss nicht in der Datenbank verschlüsselt oder verdeckt werden. Sie können es im Klartext speichern. Das Ziel ist es, den Angreifer zu zwingen, die Hashes zu knacken, sobald er die Datenbank erhalten hat, anstatt sie alle in einer Regenbogentabelle nachschlagen zu können.
Es gibt jedoch eine Einschränkung. Wenn der Angreifer leise auf ein Salt zugreifen kann, bevor in Ihre Datenbank eindringt, z. Durch ein Skript, das das Salz jedem anbietet, der danach fragt, kann er so einfach wie möglich einen Regenbogentisch für dieses Salz erstellen, wenn es keinen gäbe. Dies bedeutet, dass er stillschweigend das Salz Ihres Administratorkontos nehmen und eine schöne große Regenbogentabelle erstellen kann, sich dann in Ihre Datenbank hackt und sich sofort als Administrator anmeldet. Dies gibt Ihnen keine Zeit, um festzustellen, dass ein Verstoß aufgetreten ist, und keine Zeit, Maßnahmen zu ergreifen, um Schäden zu verhindern, z. Ändern Sie das Administratorkennwort / sperren Sie privilegierte Konten. Dies bedeutet nicht, dass Sie Ihre Salze verdecken oder versuchen sollten, sie zu verschlüsseln. Es bedeutet lediglich, dass Sie Ihr System so gestalten sollten, dass sie nur durch Einbruch in die Datenbank an die Salze gelangen können.
Eine weitere zu berücksichtigende Idee ist ein Pfeffer. Ein Pfeffer ist ein zweites Salz, das zwischen einzelnen Passwörtern konstant ist, aber nicht in der Datenbank gespeichert ist. Wir könnten es als H (Salz + Passwort + Pfeffer)
oder KDF (Passwort + Pfeffer, Salz)
für eine Schlüsselableitungsfunktion implementieren - wir werden darüber sprechen später. Ein solcher Wert kann im Code gespeichert sein. Dies bedeutet, dass der Angreifer Zugriff auf die Datenbank und den Quellcode (oder Webapp-Binärdateien im Fall von ASP .NET, CGI usw.) haben muss, um zu versuchen, die Hashes zu knacken. Diese Idee sollte nur verwendet werden, um andere Sicherheitsmaßnahmen zu ergänzen. Ein Pfeffer ist nützlich, wenn Sie sich Sorgen über SQL-Injection-Angriffe machen, bei denen der Angreifer nur Zugriff auf die Datenbank hat. Dieses Modell wird jedoch (langsam) seltener, wenn Benutzer zu parametrisierten Abfragen wechseln. Sie verwenden parametrisierte Abfragen, richtig? Einige argumentieren, dass ein Pfeffer Sicherheit durch Dunkelheit darstellt, da Sie nur den Pfeffer verdecken, was etwas wahr ist, aber es ist nicht zu sagen, dass die Idee unbegründet ist.
Jetzt sind wir in einer Situation Hier kann der Angreifer jeden einzelnen Kennwort-Hash brutal erzwingen, aber nicht mehr nach allen Hashes in einer Regenbogentabelle suchen und Klartext-Kennwörter sofort wiederherstellen. Wie verhindern wir jetzt Brute-Force-Angriffe?
Moderne Grafikkarten enthalten GPUs mit Hunderten von Kernen. Jeder Kern ist sehr gut in Mathematik, aber nicht sehr gut in der Entscheidungsfindung. Es kann Milliarden von Berechnungen pro Sekunde ausführen, aber es ist ziemlich schrecklich bei Operationen, die eine komplexe Verzweigung erfordern. Kryptografische Hash-Algorithmen passen in die erste Art der Berechnung. Daher können Frameworks wie OpenCL und CUDA genutzt werden, um den Betrieb von Hash-Algorithmen massiv zu beschleunigen. Führen Sie oclHashcat mit einer anständigen Grafikkarte aus, und Sie können einen Überschuss von 10.000.000.000 MD5-Hashes pro Sekunde berechnen. SHA-1 ist auch nicht viel langsamer. Es gibt Leute mit dedizierten GPU-Cracking-Rigs, die 6 oder mehr Top-End-Grafikkarten enthalten, was zu einer Cracking-Rate von über 50 Milliarden Hashes pro Sekunde für MD5 führt. Lassen Sie mich das in einen Zusammenhang bringen: Ein solches System kann ein 8-stelliges alphanumerisches Passwort in weniger als 4 Minuten brutal erzwingen.
Hashes wie MD5 und SHA-1 sind eindeutig viel zu schnell für diese Art von Situation. Ein Ansatz hierfür besteht darin, Tausende von Iterationen eines kryptografischen Hash-Algorithmus durchzuführen:
Hash = H (H (H (H (H (H (H (H (H (H (H))) H (H (H (H (... H (Passwort + Salz) + Salz) + Salz) ...)
Dies verlangsamt die Hash-Berechnung, ist aber nicht perfekt Einige befürworten die Verwendung von SHA-2 -Familien-Hashes, dies bietet jedoch nicht viel zusätzliche Sicherheit. Ein soliderer Ansatz besteht darin, eine Schlüsselableitungsfunktion mit einem Arbeitsfaktor zu verwenden. Diese Funktionen verwenden ein Kennwort, a Salz und ein Arbeitsfaktor. Der Arbeitsfaktor ist eine Möglichkeit, die Geschwindigkeit des Algorithmus an Ihre Hardware- und Sicherheitsanforderungen anzupassen:
hash = KDF (Kennwort, Salt, workFactor)
Die beiden beliebtesten KDFs sind PBKDF2 und bcrypt. PBKDF2 führt Iterationen eines verschlüsselten HMAC durch (obwohl es Blockchiffren verwenden kann), und bcrypt berechnet und kombiniert eine große Anzahl von Chiffretextblöcken aus der Blowfish -Blockchiffre. Beide machen ungefähr den gleichen Job. Eine neuere Variante von bcrypt namens scrypt funktioniert nach dem gleichen Prinzip, führt jedoch eine speicherintensive Operation ein, die das Knacken von GPUs und FPGA -Farmen aufgrund der Speicherbandbreite vollständig unmöglich macht Einschränkungen.
Update: Ab Januar 2017 ist der hochmoderne Hashing-Algorithmus der Wahl Argon2, der gewonnen hat Der Passwort-Hashing-Wettbewerb.
Hoffentlich gibt Ihnen dies einen schönen Überblick über die Probleme, mit denen wir beim Speichern von Passwörtern konfrontiert sind, und beantwortet Ihre Frage zur Salzspeicherung. Ich empfehle dringend, die "Links von Interesse" am Ende von Jaccos Antwort zur weiteren Lektüre sowie die folgenden Links zu lesen: