Wo lagern Sie Ihre Salzfäden?

250

Ich habe immer eine richtige Salt-Zeichenfolge pro Eintrag verwendet, wenn Kennwörter für die Datenbankspeicherung gehasht wurden. Für meine Bedürfnisse hat das Speichern des Salt in der Datenbank neben dem Hash-Passwort immer gut funktioniert.

Einige Leute empfehlen jedoch, das Salz getrennt von der Datenbank zu lagern. Ihr Argument ist, dass ein Angreifer, wenn die Datenbank kompromittiert ist, immer noch eine Regenbogentabelle erstellen kann, die eine bestimmte Salzkette berücksichtigt, um jeweils ein Konto zu knacken. Wenn dieses Konto über Administratorrechte verfügt, muss er möglicherweise nicht einmal andere knacken.

Lohnt es sich aus Sicherheitsgründen, Salze an einem anderen Ort zu lagern? Stellen Sie sich eine Webanwendung mit dem Servercode und der Datenbank auf demselben Computer vor. Wenn die Salze in einer flachen Datei auf diesem Computer gespeichert sind, besteht die Möglichkeit, dass bei einer Kompromittierung der Datenbank auch die Salzdatei gespeichert wird.

Gibt es dafür empfohlene Lösungen?

Friedo
quelle
9
Wenn es einen Ort gibt, an dem Sie das Salz speichern können, an das der Angreifer nicht gelangen kann, sollten Sie auch die Passwörter dort speichern. Aber warum nicht für jedes Passwort ein anderes Salz verwenden?
Jrockway
8
Er verwendet für jedes Passwort ein anderes Salz, Jrockway.
Amber
9
Wie groß sind deine Salze? Ihre Salze sollten groß genug sein (32 Bit?), Dass praktisch keine Chance besteht, dass ein Regenbogentisch dafür vorberechnet wurde.
M. Dudley
@emddudley In diesen Tagen habe ich mir angewöhnt, eine 64-Bit-Ganzzahl als Salz zu verwenden, aber es gibt keinen Grund, warum ich sie nicht länger machen kann.
Friedo
10
Autor von PWDTK hier sourceforge.net/projects/pwdtknet , ehrlich gesagt würde ich mir keine Sorgen machen und ich würde nur Salz in derselben Datenbank wie das Passwort speichern. Sie sollten immer davon ausgehen, dass einem Angreifer ohnehin Salz bekannt ist. Daher sollten Sie sich darauf konzentrieren, ein GROSSES CRYPTO-RANDOM-Salz zu verwenden und eine ausreichende Dehnung der Schlüssel (Iterationen in PBKDF2) durchzuführen, damit nicht einmal eine Regenbogentabelle für ein bekanntes Salz erstellt werden kann. Ehrlich gesagt ist das, was Sie erreichen möchten, indem Sie das Salz an anderer Stelle ablegen, "Sicherheit durch Dunkelheit" und hat im Allgemeinen keinen Nutzen, wenn Sie sich Dinge wie einen anderen Server ansehen, der möglicherweise ausfällt.
Thashiznets

Antworten:

259

Der Punkt bei Regenbogentabellen ist, dass sie im Voraus erstellt und massenweise verteilt werden, um Rechenzeit für andere zu sparen. Das Generieren von Regenbogentabellen im laufenden Betrieb dauert genauso lange wie das direkte Knacken der Kombination aus Passwort und Salz (seitdem) Tatsächlich wird beim Generieren von Regenbogentabellen die Berechnungen für das brutale Erzwingen des Hash vorab ausgeführt. Daher ist das Argument, dass jemand "eine Regenbogentabelle generieren" könnte, wenn er das Salz kennt, falsch.

Es macht keinen Sinn, Salze in einer separaten Datei zu speichern, solange sie auf Benutzerbasis vorliegen. Der Sinn des Salzes besteht einfach darin, es so zu gestalten, dass eine Regenbogentabelle nicht jedes Kennwort in der Datenbank brechen kann.

Bernstein
quelle
17
Einverstanden. Das Bedrohungsmodell, vor dem Sie schützen, indem Sie das Salz separat speichern, ist ein Benutzer, der auf schändliche Weise auf das Salz in der Datenbank zugreifen kann, nicht jedoch auf den Hash (in der Datenbank). Und diese Person beginnt im Voraus mit der Berechnung einer Regenbogentabelle, vorausgesetzt, sie kann den Hash später finden. Nicht unmöglich, aber auch den technischen Aufwand für die Verteidigung gegen diese einzelne Angriffsstraße nicht wert.
Tom Ritter
Netter Beitrag, ich habe mich das Gleiche gefragt. Ich habe nie über ein Salz pro Benutzer nachgedacht. Ich dachte, dass ein einziges Salz für alle Benutzer funktionieren würde. Was ist mit einem Salt, das als XML-Datei gespeichert ist, die vom App Server geladen wird? oder vielleicht irgendwie fest in ein Servlet codiert?
Jigzat
9
@ Jigzat - Salting ist sinnlos, wenn Sie nicht für jeden Benutzer ein eigenes Salt haben. Der Sinn von Salzen besteht darin, das Brechen der Hashes zu einer separaten Aufgabe für jedes Benutzerkennwort zu machen. Wenn das Salz für alle gleich ist, ist das nicht der Fall.
Amber
3
@ TomRitter das ist nicht der einzige Fall. Sie gehen davon aus, dass alle Passwörter kompliziert sind. Einige Angreifer nehmen möglicherweise das Salz und den Hash und überprüfen nur die 10.000 häufigsten Passwörter. Auf diese Weise erhalten sie eine anständige Anzahl von Menschen. Wenn sie jedoch keinen Zugriff auf das Salt haben, entspricht dies dem Benutzer mit einem längeren, sichereren Kennwort. Wie wahrscheinlich es ist, dass die Salt-Datenbank sicher bleibt, während die Passwortdatenbank gestohlen wird, steht zur Debatte, aber das ist ein separates Problem.
Chacham15
@ Amber, ich glaube TomRitter ist richtig. Das Salz separat zu speichern bedeutet den Unterschied zwischen dem Erzwingen eines Brute-Force-Angriffs durch einen Angreifer und einem einfacheren Wörterbuchangriff. Wenn Sie das Salz kennen, können Sie es einfach während eines Angriffs auf das Mühlenwörterbuch anhängen. Wenn Sie Ihr Salz zu 100% verteidigen können, können Sie einfach dasselbe Salz verwenden und Angreifer dazu zwingen, alles brutal zu erzwingen (auch für Benutzer, die "Passwort" als Passwort verwenden). Aber kannst du dein Salz verteidigen ... wahrscheinlich nicht. Sie können also auch Fehlerquellen reduzieren, indem Sie sie neben dem Hash speichern und strengere Kennwortregeln durchsetzen.
Ultratrunks
35

Ich werde dies etwas anders betrachten.

Ich speichere immer das Salz, das mit dem gesalzenen Passwort-Hash gemischt ist.

Zum Beispiel werde ich die erste Hälfte des Salzes vor dem gesalzenen Hash des Passworts und die letzte Hälfte des Salzes nach dem gesalzenen Hash des Passworts platzieren. Die Anwendung kennt dieses Design, kann also diese Daten abrufen und den Salt- und Salted-Password-Hash abrufen.

Meine Begründung für diesen Ansatz:

Wenn die Passwort- / Hash-Daten kompromittiert sind und in die Hände eines Angreifers fallen, weiß der Angreifer nicht, was das Salz ist, wenn er sich die Daten ansieht. Auf diese Weise kann ein Angreifer praktisch keinen Brute-Force-Angriff ausführen, um ein Kennwort zu erhalten, das dem Hash entspricht, da er den Hash zunächst nicht kennt und nicht wissen kann, welche Teile der Daten Teile des Salt sind, oder Teile des Salted-Password-Hash (es sei denn, er kennt die Authentifizierungslogik Ihrer Anwendung ).

Wenn der gesalzene Passwort-Hash unverändert gespeichert wird, kann ein Brute-Force-Angriff ausgeführt werden, um ein Passwort zu erhalten, das beim Saltieren und Hashing dieselben Daten wie der gesalzene Passwort-Hash erzeugt.

Selbst wenn beispielsweise der gesalzene Passwort-Hash unverändert gespeichert, aber mit einem einzelnen zufälligen Byte vorangestellt wird, würde dies ebenfalls die Schwierigkeit erhöhen, solange der Angreifer nicht weiß, dass dieses erste Byte verworfen werden soll des Angriffs. Ihre Anwendung kann das erste Byte der Daten verwerfen, wenn sie zur Authentifizierung Ihres Benutzers verwendet wird.

Der Abschluss dazu ..

1) Speichern Sie niemals die Daten, die Ihre Authentifizierungsanwendung verwendet, in exakter Form.

2) Wenn möglich, halten Sie Ihre Authentifizierungslogik für zusätzliche Sicherheit geheim.

Gehen Sie noch einen Schritt weiter.

Wenn Sie die Authentifizierungslogik Ihrer Anwendung nicht geheim halten können, wissen viele Leute, wie Ihre Daten in der Datenbank gespeichert sind. Angenommen, Sie haben beschlossen, den gesalzenen Passwort-Hash zusammen mit dem Salz zu mischen, wobei ein Teil des Salzes dem gesalzenen Passwort-Hash vorangestellt ist und der Rest des Salzes ihn anhängt.

Bei der Generierung des zufälligen Salzes können Sie auch zufällig entscheiden, welchen Anteil Ihres Salzes Sie vor / nach dem gesalzenen Passwort-Hash speichern.

Beispielsweise generieren Sie ein zufälliges Salz von 512 Bytes. Sie hängen das Salt an Ihr Passwort an und erhalten den SHA-512-Hash Ihres Salted-Passworts. Sie generieren auch eine zufällige Ganzzahl 200. Anschließend speichern Sie die ersten 200 Bytes des Salzes, gefolgt vom gesalzenen Passwort-Hash, gefolgt vom Rest des Salzes.

Bei der Authentifizierung der Kennworteingabe eines Benutzers geht Ihre Anwendung über die Zeichenfolge und geht davon aus, dass das erste 1-Byte der Daten das erste 1-Byte des Salt ist, gefolgt vom Salted-Hash. Dieser Pass wird fehlschlagen. Die Anwendung wird fortgesetzt, indem die ersten 2 Bytes der Daten als die ersten 2 Bytes des Salzes verwendet werden, und wiederholt, bis ein positives Ergebnis gefunden wird, nachdem die ersten 200 Bytes als die ersten 200 Bytes des Salzes verwendet wurden. Wenn das Kennwort falsch ist, versucht die Anwendung weiterhin alle Permutationen, bis keine gefunden werden.

Die Vorteile dieses Ansatzes:

Erhöhte Sicherheit - selbst wenn Ihre Authentifizierungslogik bekannt ist, ist die genaue Logik zur Kompilierungszeit unbekannt. Es ist praktisch unmöglich, einen Brute-Force-Angriff durchzuführen, selbst wenn die genaue Logik bekannt ist. Erhöhte Salzlängen erhöhen die Sicherheit weiter.

Die Nachteile dieses Ansatzes:

Da die genaue Logik zur Laufzeit abgeleitet wird, ist dieser Ansatz sehr CPU-intensiv. Je länger das Salz ist, desto CPU-intensiver wird dieser Ansatz.

Die Authentifizierung falscher Passwörter ist mit den höchsten CPU-Kosten verbunden. Dies kann für legitime Anfragen kontraproduktiv sein, erhöht jedoch die Sicherheit gegen Angreifer.

Dieser Ansatz kann auf verschiedene Arten implementiert und durch Verwendung von Salzen mit variabler Breite und / oder gesalzenen Passwort-Hashes noch sicherer gemacht werden.

Ibraheem
quelle
9
Mit Ihrem Ansatz fügen Sie Ihrem Hashing-Prozess lediglich ein Geheimnis hinzu (den Algorithmus, der das Salz anwendet). Dieses Geheimnis können Sie viel einfacher hinzufügen, indem Sie dem Salz zusätzlich einen Pfeffer hinzufügen. Ich habe versucht, dies in meinem Tutorial herauszustellen . Moderne Hash-Funktionen wie BCrypt wenden das Salt selbst an und verwenden dabei das ursprüngliche Salt in jeder Iteration, sodass Sie ohnehin keine Kontrolle darüber haben.
Martinstoeckli
@martinstoeckli Während Sie richtig sind, dass BCrypt das Salz selbst anwendet, liegt die Speicherung dieses Salt + Hash bei Ihnen als Entwickler. Sie können also leicht einen Pfeffer zum Salz + Hash hinzufügen und ihn in der Datenbank speichern. Beim anschließenden Abrufen lesen Sie dann den Wert aus der Datenbank, entfernen den Pfefferwert und übergeben den verbleibenden Wert an BCrypt.
PeterToTheThird
2
@PeterToTheThird - Dies würde den Vorteil des Pfeffers zunichte machen. Der Pfeffer fügt ein serverseitiges Geheimnis hinzu und funktioniert nur so lange, wie er geheim bleibt (im Gegensatz zum Salz). Ein typischer Angriff ist die SQL-Injektion. Wenn jemand Zugriff auf die Datenbank erhält, jedoch nicht auf den Code, ist ein in der Datenbank gespeicherter Pfeffer dann unbrauchbar. Die meisten BCrypt-Implementierungen fügen das Salt automatisch zum resultierenden Hash-Wert hinzu, sodass dieser Wert bereits das Salt, den Kostenfaktor, den Algorithmus und den Hash enthält. Diese Zeichenfolge kann in einem einzelnen Feld mit einer Länge von 60 Zeichen gespeichert werden.
Martinstoeckli
Wenn Sie eine "Schlüsselverstärkungs" -Funktion wie BCrypt verwenden, haben Sie keine Kontrolle über die Verwendung des Salzes. Wenn Sie jedoch einen Pfeffer verwenden möchten, hängen Sie den Pfeffer einfach an das Salz an und verwenden diesen als "Pfeffersalz" anstelle des "Salz" -Eingangs für die Hashing-Funktion. Der "Pfeffer" ist dann ein geeignetes Datenelement, das nicht in der Datenbank gespeichert, sondern in den Authentifizierungscode eingebettet oder an einem anderen sicheren Ort gespeichert ist. Ich habe das Problem aus einer generischen Perspektive betrachtet und SHA-512 als Beispielfunktion verwendet, aber BCrypt usw. kann auch auf ähnliche Weise verwendet werden.
Ibraheem
2
@martinstoeckli - ja, die tatsächliche Implementierung hängt davon ab, welche Hash-Funktion Sie verwenden. Natürlich müssen Sie bei der Implementierung Ihrer Authentifizierungslogik die Parameter und Ausgaben der Hash-Funktion berücksichtigen. Letztendlich ist ein Pfeffer nur eine weitere Variable, die in Ihre Hashing-Funktion eingeführt wird und nicht an derselben Stelle wie Salz und Hasch gespeichert wird.
Ibraheem
23

Oft werden sie dem Hash vorangestellt und im selben Feld gespeichert.

Sie müssen nicht separat gespeichert werden. Es geht darum, für jedes Kennwort ein zufälliges Salz zu verwenden, damit eine einzelne Regenbogentabelle nicht für Ihren gesamten Satz von Kennwort-Hashes verwendet werden kann. Bei zufälligen Salzen muss ein Angreifer jeden Hash einzeln brutal erzwingen (oder eine Regenbogentabelle für alle möglichen Salze berechnen - viel mehr Arbeit).

Wenn Sie einen sichereren Speicherort hätten, wäre es sinnvoll, nur die Hashes dort zu speichern.

niemand
quelle
4
Aber was passiert, wenn alle gehashten Passwörter einschließlich des passenden Salt durchgesickert sind? Ist das nicht genauso unsicher?
mghaoui
10
@mghaoui Aber wenn Sie das "Passwort" wissen wollen, müssen Sie immer noch eine Regenbogentabelle für jedes Salz erstellen, es sei denn, einige der Salze sind gleich.
Franklin
4

Basierend auf der Entwicklung des ASP.NET MVC 4-Webanwendungsbuchs von William Penberthy:

  1. Um Zugriff auf die in einer separaten Datenbank gespeicherten Salze zu erhalten, müssen Hacker zwei verschiedene Datenbanken hacken, um Zugriff auf das Salt und das gesalzene Passwort zu erhalten. Das Speichern in derselben Tabelle wie das Kennwort oder sogar in einer anderen Tabelle derselben Datenbank würde bedeuten, dass Hacker, wenn sie Zugriff auf die Datenbank erhalten, sowohl auf den Salt- als auch auf den Kennwort-Hash zugreifen können. Da Sicherheit den Prozess umfasst, das Hacken in das System zu teuer oder zeitaufwändig zu machen, um es wert zu sein, sollte eine Verdoppelung des Zugriffs, den ein Hacker erhalten müsste, das System sicherer machen.
  2. Die Benutzerfreundlichkeit ist der Hauptgrund dafür, dass die Salze in derselben Datenbank wie die Hash-Passwörter gespeichert werden. Sie müssten nicht sicherstellen, dass zwei Datenbanken immer gleichzeitig und immer synchron verfügbar sind. Der Vorteil eines Salt ist minimal, wenn jeder Benutzer ein zufälliges Salt hat, denn obwohl dies das Auffinden des Kennworts einer Person erleichtern könnte, ist der Kraftaufwand zum Knacken der Kennwörter des Systems insgesamt hoch. In dieser Diskussionsebene ist das wirklich die Erwartung: die Passwörter zu schützen. Wenn die Hacker eine Kopie der Datenbank erworben haben, sind Ihre Anwendungsdaten bereits gefährdet. An diesem Punkt besteht das Problem darin, die Risiken der Benutzer aufgrund des Potenzials gemeinsamer Kennwörter zu verringern.
  3. Die Anforderung, zwei separate verknüpfte Datenbanken zu verwalten, ist umfangreich. Zugegeben, es fügt die Wahrnehmung von Sicherheit hinzu, aber der einzige Vorteil, den es bietet, ist, dass es ein Passwort schützt, ein einzelnes Datenelement. Wenn jedes Feld in der Datenbank einzeln verschlüsselt wäre und dasselbe Salz dafür verwendet würde, wäre es sinnvoller, es getrennt von den Daten zu speichern, da die grundlegende Sicherheit Ihres Systems verbessert wird.
DaNeSh
quelle
Wenn sich die Anwendung jedoch bei beiden Datenbanken authentifizieren kann, ist dies nicht im Wesentlichen dasselbe wie bei einer Datenbank, wenn der Angreifer den Anwendungscode kompromittiert hat?
John Ernest
0

Der Sinn eines Salzes besteht darin, alle Regenbogentabellen unbrauchbar zu machen und einen neuen Satz davon zu erstellen. Das Erraten einer Schnur dauert genauso lange wie das Erstellen eines Regenbogentisches. Zum Beispiel ist der SHA-256-Hash von "Passwort" 5e88 4898 da28 0471 51d0 e56f 8dc6 2927 7360 3d0d 6aab bdd6 2a11 ef72 1d15 42d8. Nachdem ein Salt hinzugefügt wurde, z. B. "badpassword", lautet die neue zu hashende Zeichenfolge "passwordbadpassword", wodurch sich die Ausgabe aufgrund des Lawineneffekts dramatisch ändert 457b f8b5 37f1 802e f9c8 2e46 b8d3 f8b5 721b 7cbb d485 f0bb e523 bfbe 73e6 58d6.

Normalerweise wird das Salt nur in derselben Datenbank wie das Passwort gespeichert, auch weil es wahrscheinlich ist, dass die andere Datenbank gehackt wird, wenn eine Datenbank gehackt wird.

Eric Jin
quelle