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.