Web-App-Passwörter: bcrypt und SHA256 (und scrypt)

Bei all den jüngsten (z. B. LinkedIn) Diskussionen über Passwörter habe ich mich mit Implementierungen von Passwort-Hashing befasst. Nach zwei Tassen Kaffee und einer morgendlichen Lektüre bin ich kein Kryptograf mehr als zu Beginn. Und ich möchte wirklich nicht so tun, als wäre ich es.

Spezifische Fragen

Schlägt die Verwendung einer ganzzahligen eindeutigen Benutzer-ID als effektives Salt fehl? (crypt () verwendet nur 16 Bits?)

Wenn ich sha256 () für einen Hash einfach immer wieder ausführe, bis eine Sekunde vergangen ist, sind dann die Brute-Force-Angriffe besiegt?

Wenn ich diese Fragen stellen muss, sollte ich bcrypt verwenden?

Diskussion / Erklärung:

Das Ziel ist einfach, wenn die gehashten Passwörter meiner Benutzer durchgesickert sind:

wäre nicht "leicht" zu knacken,Das Knacken eines Kennworts würde andere Benutzer, die dasselbe Kennwort verwenden, nicht aussetzen.

Was ich für # 1 gelesen habe, ist, dass die Hash-Berechnung teuer sein muss - beispielsweise ein oder zwei Sekunden, um sie zu berechnen, und möglicherweise ein bisschen oder Speicher (um die Hardware-Entschlüsselung zu vereiteln).

bcrypt hat dies eingebaut und scrypt ist, wenn ich das richtig verstehe, zukunftssicherer und beinhaltet eine minimale Speicheranforderung.

Aber ist es ein ebenso effektiver Ansatz, die Zeit zu essen, indem das Ergebnis von sha256 () so oft "nachgewärmt" wird, bis einige Sekunden vergangen sind, und dann die endgültige Schleifenzahl mit dem Hash gespeichert wird, um später ein angegebenes Passwort zu überprüfen?

Für # 2 ist es wichtig, ein eindeutiges Salt für jedes Passwort zu verwenden. Was nicht klar war, ist, wie zufällig (oder groß) das Salz sein muss. Wenn das Ziel ist, zu vermeiden, dass jeder, der "mypassword" als Passwort verwendet, denselben Hash hat, ist es nicht genug, dies einfach zu tun ?:

hash = sha256_hex( unique_user_id + user_supplied_password );

oder auch das, obwohl ich nicht sicher bin, ob es mir etwas kauft:

hash = sha256_hex( sha256( unique_user_id ) + user_supplied_password );

Der einzige Vorteil, den ich aus der Verwendung der Benutzer-ID ziehen kann, ist, dass ich nicht das Salz zusammen mit dem Hash speichern muss. Kein großer Vorteil. Gibt es ein echtes Problem bei der Verwendung einer Benutzer-ID als Salt? Schafft es nicht # 2?

Ich gehe davon aus, dass jemand, der die Hash-Passwörter meines Benutzers stehlen kann, alles bekommen kann, was er will - einschließlich des Quellcodes, der den Hash generiert. Gibt es also einen Vorteil, wenn Sie dem Kennwort vor dem Hashing eine zusätzliche zufällige Zeichenfolge (dieselbe Zeichenfolge) hinzufügen? Das ist:

# app_wide_string = one-time generated, random 64 7-bit *character* string.
hash = sha256_hex( unique_user_id + app_wide_string + user_supplied_password );

Ich habe den Vorschlag gesehen, aber ich verstehe nicht, was ich davon über das Salz pro Benutzer gewinne. Wenn jemand den Angriff brachial erzwingen wollte, würde er diesen "app_wide_string" kennen und diesen beim Ausführen seines Wörterbuchangriffs verwenden, oder?

Gibt es einen guten Grund, bcrypt anstelle des oben beschriebenen Rollens zu verwenden? Vielleicht ist die Tatsache, dass ich diese Fragen stelle, Grund genug?

Übrigens: Ich habe gerade eine vorhandene Hashing-Funktion zeitlich festgelegt, die ich auf meinem Laptop habe, und ich kann ungefähr 7000 Hashes pro Sekunde generieren. Nicht ganz die ein oder zwei Sekunden, die oft vorgeschlagen werden.

Einige verwandte Links:

Verwenden von sha256 als Hashing und Salting mit der Benutzer-ID

SHA512 gegen Blowfish und Bcrypt

Was ist die optimale Länge für das Benutzerkennwort salt?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage