In Coda Hales Artikel "So speichern Sie ein Passwort sicher" heißt es:
In bcrypt sind Salze eingebaut, um Regenbogentischangriffe zu verhindern.
Er zitiert dieses Papier , das besagt, dass in der OpenBSD-Implementierung von bcrypt
:
OpenBSD generiert das 128-Bit-bcrypt-Salt aus einem arcfour-Schlüsselstrom (arc4random (3)), der mit zufälligen Daten versehen ist, die der Kernel aus Geräte-Timings sammelt.
Ich verstehe nicht, wie das funktionieren kann. In meiner Vorstellung von einem Salz:
- Es muss für jedes gespeicherte Passwort unterschiedlich sein, damit für jedes eine separate Regenbogentabelle generiert werden muss
- Es muss irgendwo gespeichert werden, damit es wiederholbar ist: Wenn ein Benutzer versucht, sich anzumelden, versuchen wir es mit seinem Kennwort, wiederholen den gleichen Salt-and-Hash-Vorgang wie bei der ursprünglichen Speicherung seines Kennworts und vergleichen
Wenn ich Devise (einen Rails-Anmeldemanager) mit bcrypt verwende, befindet sich keine Salzspalte in der Datenbank, daher bin ich verwirrt. Wenn das Salz zufällig ist und nirgendwo gelagert wird, wie können wir den Hashing-Prozess zuverlässig wiederholen?
Kurz gesagt, wie kann bcrypt eingebaute Salze haben ?
"OrpheanBeholderScryDoubt"
Ich glaube, dieser Satz hätte wie folgt formuliert werden müssen:
Das
bcrypt
Dienstprogramm selbst scheint keine Liste von Salzen zu führen. Vielmehr werden Salze zufällig generiert und an die Ausgabe der Funktion angehängt, damit sie später gespeichert werden (gemäß der Java-Implementierung vonbcrypt
). Anders ausgedrückt, der von erzeugte "Hash"bcrypt
ist nicht nur der Hash. Es ist vielmehr der Hasch und das Salz verkettet.quelle
Bcrypt
fügt ein zufälliges Salz von "akd2! *" hinzu, was zu "fooakd2! *" führt, das gehasht und gespeichert wird. Später versuche ich mich mit dem Passwort "bar" anzumelden. Um zu sehen, ob ich richtig bin, muss es "barakd2! *" Hash. Wenn das Salz zunächst zufällig generiert wurde, woher weiß es dann, wie es vor dem Hashing und Vergleichen wieder zu "bar" hinzugefügt werden kann?bcrypt
weiß, wie man das Salz wieder aus der generierten Ausgabe (die in der Datenbank gespeichert ist) extrahiert. Wenn es Zeit für die Authentifizierung ist,bcrypt
wird die ursprüngliche Ausgabe in ihre Hash- und Salt-Komponenten aufgeteilt. Die Salt-Komponente wird auf das vom Benutzer eingegebene eingehende Kennwort angewendet.Um die Dinge noch klarer zu machen,
Registrierungs- / Login-Richtung ->
Das Passwort + Salt wird mit einem Schlüssel verschlüsselt, der aus den Kosten, Salt und dem Passwort generiert wird. Wir nennen diesen verschlüsselten Wert den
cipher text
. Dann hängen wir das Salt an diesen Wert an und codieren ihn mit base64. Anhängen der Kosten daran und dies ist die produzierte Zeichenfolge ausbcrypt
:$2a$COST$BASE64
Dieser Wert wird schließlich gespeichert.
Was müsste der Angreifer tun, um das Passwort zu finden? (andere Richtung <-)
Falls der Angreifer die Kontrolle über die Datenbank erlangt hat, dekodiert der Angreifer den base64-Wert leicht und kann dann das Salz sehen. Das Salz ist nicht geheim. obwohl es zufällig ist. Dann muss er das entschlüsseln
cipher text
.Was wichtiger ist: In diesem Prozess gibt es kein Hashing, sondern eine CPU-teure Verschlüsselung - Entschlüsselung. Daher sind Regenbogentabellen hier weniger relevant.
quelle
Dies stammt aus der PasswordEncoder-Schnittstellendokumentation von Spring Security.
Das heißt, man muss rawPassword abgleichen, das der Benutzer bei der nächsten Anmeldung erneut eingibt, und es mit dem Bcrypt-codierten Passwort abgleichen, das während der vorherigen Anmeldung / Registrierung in der Datenbank gespeichert wurde.
quelle