Da regelmäßig Fragen zum Salzen von Hashes gestellt werden und das Thema ziemlich verwirrend zu sein scheint, habe ich diese Antwort erweitert.
Was ist ein Salz?
Ein Salt ist eine zufällige Menge von Bytes fester Länge, die zur Eingabe eines Hash-Algorithmus hinzugefügt werden.
Warum ist das Salzen (oder Säen) eines Hash nützlich?
Durch Hinzufügen eines zufälligen Salt zu einem Hash wird sichergestellt, dass dasselbe Kennwort viele verschiedene Hashes erzeugt. Das Salz wird normalerweise zusammen mit dem Ergebnis der Hash-Funktion in der Datenbank gespeichert. Das Salzen eines Hashs ist aus mehreren Gründen gut:
- Das Salzen erhöht die Schwierigkeit / die Kosten vorberechneter Angriffe (einschließlich Regenbogentabellen ) erheblich.
- Durch das Salting wird sichergestellt, dass dasselbe Kennwort nicht zu demselben Hash führt. Dadurch wird sichergestellt, dass Sie nicht feststellen können, ob zwei Benutzer dasselbe Kennwort haben. Und was noch wichtiger ist , Sie können nicht feststellen, ob dieselbe Person auf verschiedenen Systemen dasselbe Kennwort verwendet.
Salting erhöht die Komplexität von Passwörtern und verringert dadurch die Effektivität von Dictionary- und Birthday-Angriffen erheblich . (Dies gilt nur , wenn das Salz wird aus dem Hash separate gespeichert).
- Durch korrektes Salzen wird der Speicherbedarf für Vorberechnungsangriffe erheblich erhöht, bis sie nicht mehr praktikabel sind. (8-stellige alphanumerische Passwörter mit 16-Bit-Salt, die auf einen 128-Bit-Wert gehasht wurden, würden ohne Regenbogenreduzierung knapp 200 Exabyte belegen).
Das Salz muss nicht geheim sein.
Ein Salt ist kein geheimer Schlüssel, sondern ein Salt "funktioniert", indem es die Hash-Funktion für jede Instanz spezifisch macht. Bei gesalzenem Hash gibt es nicht eine Hash-Funktion, sondern eine für jeden möglichen Salzwert. Dies verhindert, dass der Angreifer N gehashte Passwörter für weniger als das N- fache der Kosten für den Angriff auf ein Passwort angreift. Dies ist der Punkt des Salzes.
Ein "geheimes Salt" ist kein Salt, es wird als "Schlüssel" bezeichnet und bedeutet, dass Sie keinen Hash mehr berechnen, sondern einen Message Authentication Code (MAC). Das Berechnen von MAC ist eine knifflige Angelegenheit (viel schwieriger als das einfache Zusammenfügen eines Schlüssels und eines Werts zu einer Hash-Funktion) und ein ganz anderes Thema.
Das Salz muss für jeden Fall, in dem es verwendet wird , zufällig sein . Dies stellt sicher, dass ein Angreifer jeden gesalzenen Hash separat angreifen muss.
Wenn Sie sich darauf verlassen, dass Ihr Salz (oder Salzalgorithmus) geheim ist, betreten Sie die Bereiche Sicherheit durch Dunkelheit (funktioniert nicht). Höchstwahrscheinlich erhalten Sie keine zusätzliche Sicherheit durch das Salzgeheimnis. Sie bekommen nur das warme, verschwommene Gefühl der Sicherheit. Anstatt Ihr System sicherer zu machen, lenkt es Sie nur von der Realität ab.
Warum muss das Salz zufällig sein?
Technisch sollte das Salz einzigartig sein . Der Punkt des Salzes muss für jedes gehashte Passwort unterschiedlich sein. Dies ist weltweit gemeint . Da es keine zentrale Organisation gibt, die einzigartige Salze nach Bedarf verteilt, müssen wir uns auf das nächstbeste verlassen, nämlich die zufällige Auswahl mit einem unvorhersehbaren Zufallsgenerator, vorzugsweise in einem Salzraum, der groß genug ist, um Kollisionen unwahrscheinlich zu machen (zwei Instanzen, die dieselbe verwenden) Salzwert).
Es ist verlockend zu versuchen, aus einigen Daten, die "vermutlich eindeutig" sind, wie z. B. der Benutzer-ID, ein Salz abzuleiten. Solche Schemata schlagen jedoch häufig aufgrund böser Details fehl:
Wenn Sie beispielsweise die Benutzer-ID verwenden, bündeln einige Bösewichte, die unterschiedliche Systeme angreifen, möglicherweise nur ihre Ressourcen und erstellen vorberechnete Tabellen für die Benutzer-IDs 1 bis 50. Eine Benutzer-ID ist systemweit eindeutig , jedoch nicht weltweit .
Gleiches gilt für den Benutzernamen : Es gibt eine "Wurzel" pro Unix-System, aber es gibt viele Wurzeln auf der Welt. Eine Regenbogentabelle für "root" wäre die Mühe wert, da sie auf Millionen von Systemen angewendet werden könnte. Schlimmer noch, es gibt auch viele "Bob" da draußen und viele haben kein Sysadmin-Training: Ihre Passwörter könnten ziemlich schwach sein.
Einzigartigkeit ist auch zeitlich. Manchmal ändern Benutzer ihr Passwort. Für jedes neue Passwort muss ein neues Salz ausgewählt werden. Andernfalls könnte ein Angreifer den Hash des alten Passworts erhalten und der Hash des neuen könnte versuchen, beide gleichzeitig anzugreifen.
Die Verwendung eines zufälligen Salzes aus einem kryptografisch sicheren, unvorhersehbaren PRNG kann eine Art Overkill sein, schützt Sie jedoch nachweislich vor all diesen Gefahren. Es geht nicht darum, den Angreifer daran zu hindern, zu wissen, was ein einzelnes Salz ist, sondern darum, ihm nicht das große, fette Ziel zu geben, das für eine beträchtliche Anzahl potenzieller Ziele verwendet wird. Durch zufällige Auswahl werden die Ziele so dünn wie möglich.
Abschließend:
Verwenden Sie ein zufälliges, gleichmäßig verteiltes Salz mit hoher Entropie. Verwenden Sie ein neues Salz, wenn Sie ein neues Passwort erstellen oder ein Passwort ändern. Speichern Sie das Salz zusammen mit dem Hash-Passwort. Bevorzugen Sie große Salze (mindestens 10 Bytes, vorzugsweise 16 oder mehr).
Ein Salz macht aus einem schlechten Passwort kein gutes Passwort. Es stellt nur sicher, dass der Angreifer mindestens den Preis für den Wörterbuchangriff für jedes falsche Passwort zahlt, das er bricht.
Nützliche Quellen:
stackoverflow.com: Nicht zufälliges Salz für Passwort-Hashes
Bruce Schneier: Praktische Kryptographie (Buch)
Matasano Sicherheit: Genug mit den Regenbogentabellen
usenix.org: Unix-Krypta verwendet Salz seit 1976
owasp.org : Warum Salz hinzufügen
openwall.com : Salze
Haftungsausschluss:
Ich bin kein Sicherheitsexperte. (Obwohl diese Antwort von Thomas Pornin überprüft wurde )
Wenn einer der Sicherheitsexperten etwas falsch findet, kommentieren oder bearbeiten Sie diese Wiki-Antwort.
Seit Unix populär geworden ist, besteht der richtige Weg, ein Passwort zu speichern, darin, einen zufälligen Wert (das Salz) anzuhängen und ihn zu hashen. Bewahren Sie das Salz dort auf, wo Sie es später erreichen können, aber wo Sie hoffen, dass die Bösen es nicht bekommen.
Dies hat einige gute Auswirkungen. Erstens können die Bösen nicht einfach eine Liste der erwarteten Passwörter wie "Password1" erstellen, sie in eine Regenbogentabelle hashen und Ihre Passwortdatei nach Übereinstimmungen durchsuchen. Wenn Sie ein gutes Zwei-Byte-Salz haben, müssen sie 65.536 Werte für jedes erwartete Passwort generieren, und das macht die Regenbogentabelle viel weniger praktisch. Zweitens, wenn Sie das Salz von den Bösen fernhalten können, die Ihre Passwortdatei betrachten, haben Sie es viel schwieriger gemacht, mögliche Werte zu berechnen. Drittens haben Sie es den Bösen unmöglich gemacht, festzustellen, ob eine bestimmte Person auf verschiedenen Websites dasselbe Passwort verwendet.
Dazu erzeugen Sie ein zufälliges Salz. Dies sollte jede Zahl im gewünschten Bereich mit einheitlicher Wahrscheinlichkeit erzeugen. Das ist nicht schwierig; Ein einfacher linearer kongruenter Zufallszahlengenerator reicht aus.
Wenn Sie komplizierte Berechnungen haben, um das Salz herzustellen, machen Sie es falsch. Wenn Sie es basierend auf dem Passwort berechnen, machen Sie es WEG falsch. In diesem Fall komplizieren Sie lediglich den Hash und fügen kein Salz hinzu.
Niemand, der gut in Sicherheit ist, würde sich darauf verlassen, einen Algorithmus zu verbergen. Die moderne Kryptographie basiert auf Algorithmen, die ausgiebig getestet wurden, und um ausgiebig getestet zu werden, müssen sie bekannt sein. Im Allgemeinen hat es sich als sicherer erwiesen, Standardalgorithmen zu verwenden, als eigene zu rollen und zu hoffen, dass es gut ist. Es spielt keine Rolle, ob der Code Open Source ist oder nicht, es ist den Bösen immer noch oft möglich zu analysieren, was ein Programm tut.
quelle
Sie können zur Laufzeit einfach einen zufälligen Salt für jeden Datensatz generieren. Angenommen, Sie speichern gehashte Benutzerkennwörter in einer Datenbank. Sie können eine 8-stelliges zufällige Folge von Nieder- erzeugen und alphanumerischen Zeichen zur Laufzeit, prepend Großbuchstaben, die mit dem Passwort, Hash , dass String und speichern sie in der Datenbank. Da es 62 8 mögliche Salze gibt, ist die Erzeugung von Regenbogentabellen (für jedes mögliche Salz) unerschwinglich teuer; und da Sie für jeden Kennwortdatensatz ein eindeutiges Salt verwenden, kann ein Angreifer nicht jedes Kennwort knacken, selbst wenn er ein paar übereinstimmende Regenbogentabellen generiert hat .
Sie können die Parameter Ihrer Salzgenerierung basierend auf Ihren Sicherheitsanforderungen ändern. Sie könnten beispielsweise ein längeres Salz verwenden oder eine zufällige Zeichenfolge generieren, die auch Satzzeichen enthält, um die Anzahl der möglichen Salze zu erhöhen.
quelle
Verwenden Sie einen Zufallsfunktionsgenerator, um das Salz zu generieren, und speichern Sie es in der Datenbank, erstellen Sie Salz pro Zeile und speichern Sie es in der Datenbank.
Mir gefällt, wie bei der Django-Registrierung Salz erzeugt wird. Referenz: http://bitbucket.org/ubernostrum/django-registration/src/tip/registration/models.py#cl-85
Er verwendet eine Kombination aus sha, die durch eine Zufallszahl generiert wird, und dem Benutzernamen, um einen Hash zu generieren.
Sha
selbst ist bekannt dafür, stark und unzerbrechlich zu sein. Fügen Sie mehrere Dimensionen hinzu, um das Salz selbst zu erzeugen. Mit Zufallszahl, sha und der benutzerspezifischen Komponente haben Sie unzerbrechliche Sicherheit!quelle
Wie können Sie bei einer Desktop-Anwendung, die Daten verschlüsselt und auf einem Remote-Server sendet, jedes Mal ein anderes Salt verwenden?
Bei Verwendung von PKCS # 5 mit dem Kennwort des Benutzers wird ein Salt benötigt, um einen Verschlüsselungsschlüssel zu generieren und die Daten zu verschlüsseln. Ich weiß, dass es keine gute Idee ist, das Salz in der Desktop-Anwendung fest (verschleiert) zu halten.
Wenn der Remote-Server NIEMALS das Kennwort des Benutzers kennen darf, ist es dann möglich, jedes Mal ein anderes Salt zu verwenden? Wenn der Benutzer die Desktop-Anwendung auf einem anderen Computer verwendet, wie kann er die Daten auf dem Remote-Server entschlüsseln, wenn er nicht über den Schlüssel verfügt (dieser ist in der Software nicht fest codiert)?
quelle