In der letzten Woche habe ich viele Artikel über Passwort-Hashing gelesen und Blowfish scheint derzeit einer der besten Hashing-Algorithmen zu sein - aber das ist nicht das Thema dieser Frage!
Das Limit von 72 Zeichen
Blowfish berücksichtigt nur die ersten 72 Zeichen im eingegebenen Passwort:
<?php
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$hash = password_hash($password, PASSWORD_BCRYPT);
var_dump($password);
$input = substr($password, 0, 72);
var_dump($input);
var_dump(password_verify($input, $hash));
?>
Die Ausgabe ist:
string(119) "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)"
string(72) "Wow. This is a super secret and super, super long password. Let's add so"
bool(true)
Wie Sie sehen können, sind nur die ersten 72 Zeichen von Bedeutung. Twitter verwendet Blowfish aka bcrypt, um seine Passwörter zu speichern ( https://shouldichangemypassword.com/twitter-hacked.php ) und raten Sie mal: Ändern Sie Ihr Twitter-Passwort in ein langes Passwort mit mehr als 72 Zeichen und Sie können sich mit in Ihr Konto einloggen Eingabe nur der ersten 72 Zeichen.
Blowfish und Pfeffer
Es gibt sehr unterschiedliche Meinungen über das "Peppern" von Passwörtern. Einige Leute sagen, dass es unnötig ist, weil man davon ausgehen muss, dass die geheime Pfefferkette auch bekannt / veröffentlicht ist, damit sie den Hash nicht verbessert. Ich habe einen separaten Datenbankserver, daher ist es durchaus möglich, dass nur die Datenbank durchgesickert ist und nicht der konstante Pfeffer.
In diesem Fall (Pfeffer nicht durchgesickert) erschweren Sie einen Angriff auf der Grundlage eines Wörterbuchs (korrigieren Sie mich, wenn dies nicht richtig ist). Wenn Ihre Pfefferstrecke auch durchgesickert ist: nicht so schlimm - Sie haben immer noch das Salz und es ist so gut geschützt wie ein Haschisch ohne Pfeffer.
Daher denke ich, dass es zumindest keine schlechte Wahl ist, das Passwort zu ändern.
Vorschlag
Mein Vorschlag, einen Blowfish-Hash für ein Passwort mit mehr als 72 Zeichen (und Pfeffer) zu erhalten, lautet:
<?php
$pepper = "foIwUVmkKGrGucNJMOkxkvcQ79iPNzP5OKlbIdGPCMTjJcDYnR";
// Generate Hash
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$password_peppered = hash_hmac('sha256', $password, $pepper);
$hash = password_hash($password_peppered, PASSWORD_BCRYPT);
// Check
$input = substr($password, 0, 72);
$input_peppered = hash_hmac('sha256', $input, $pepper);
var_dump(password_verify($input_peppered, $hash));
?>
Dies basiert auf dieser Frage : password_verify
Rückkehr false
.
Die Frage
Was ist der sicherere Weg? Erhalten Sie zuerst einen SHA-256-Hash (der 64 Zeichen zurückgibt) oder berücksichtigen Sie nur die ersten 72 Zeichen des Passworts?
Vorteile
- Der Benutzer kann sich nicht anmelden, indem er nur die ersten 72 Zeichen eingibt
- Sie können den Pfeffer hinzufügen, ohne die Zeichenbeschränkung zu überschreiten
- Die Ausgabe von hash_hmac hätte wahrscheinlich mehr Entropie als das Passwort selbst
- Das Passwort wird von zwei verschiedenen Funktionen gehasht
Nachteile
- Nur 64 Zeichen werden verwendet, um den Blowfish-Hash zu erstellen
Edit 1: Diese Frage befasst sich nur mit der PHP-Integration von Blowfish / bcrypt. Danke für die Kommentare!
Antworten:
Das Problem hier ist im Grunde ein Problem der Entropie. Beginnen wir also dort:
Entropie pro Zeichen
Die Anzahl der Entropiebits pro Byte beträgt:
Wie wir uns verhalten, hängt also davon ab, welche Art von Charakteren wir erwarten.
Das erste Problem
Das erste Problem mit Ihrem Code ist, dass Ihr "Pfeffer" -Hash-Schritt Hex-Zeichen ausgibt (da der vierte Parameter
hash_hmac()
nicht gesetzt ist).Wenn Sie also Ihren Pfeffer einrühren, reduzieren Sie effektiv die maximale Entropie, die für das Passwort verfügbar ist, um den Faktor 2 (von 576 auf 288 mögliche Bits).
Das zweite Problem
Allerdings
sha256
bietet nur256
Bits der Entropie in erster Linie. Sie reduzieren also effektiv mögliche 576 Bit auf 256 Bit. Ihr Hash-Schritt * sofort * verliert per Definition mindestens 50% der möglichen Entropie im Passwort.Sie können dies teilweise lösen, indem Sie zu wechseln
SHA512
, wo Sie die verfügbare Entropie nur um etwa 12% reduzieren. Aber das ist immer noch ein nicht unerheblicher Unterschied. Diese 12% reduzieren die Anzahl der Permutationen um den Faktor1.8e19
. Das ist eine große Zahl ... Und das ist der Faktor, der sie reduziert ...Das zugrunde liegende Problem
Das zugrunde liegende Problem ist, dass es drei Arten von Passwörtern mit mehr als 72 Zeichen gibt. Die Auswirkungen, die dieses Stilsystem auf sie hat, werden sehr unterschiedlich sein:
Hinweis: Von hier an gehe ich davon aus, dass wir mit einem Pfeffersystem vergleichen, das
SHA512
mit Rohleistung (nicht hexadezimal) verwendet wird.Zufällige Passwörter mit hoher Entropie
Dies sind Ihre Benutzer, die Kennwortgeneratoren verwenden, die große Schlüssel für Kennwörter generieren. Sie sind zufällig (erzeugt, nicht vom Menschen ausgewählt) und haben eine hohe Entropie pro Charakter. Diese Typen verwenden High-Bytes (Zeichen> 127) und einige Steuerzeichen.
Für diese Gruppe reduziert Ihre Hashing-Funktion die verfügbare Entropie erheblich
bcrypt
.Lassen Sie mich das noch einmal sagen. Für Benutzer, die lange Passwörter mit hoher Entropie verwenden, reduziert Ihre Lösung die Stärke ihres Passworts erheblich um einen messbaren Betrag. (62 Bit Entropie für ein Kennwort mit 72 Zeichen und mehr für längere Kennwörter verloren)
Zufällige Passwörter mit mittlerer Entropie
Diese Gruppe verwendet Kennwörter, die allgemeine Symbole, aber keine hohen Bytes oder Steuerzeichen enthalten. Dies sind Ihre typisierbaren Passwörter.
Für diese Gruppe werden Sie etwas mehr Entropie freischalten (nicht erstellen, aber mehr Entropie in das bcrypt-Passwort einpassen lassen). Wenn ich etwas sage, meine ich etwas. Die Gewinnschwelle tritt auf, wenn Sie die 512 Bits von SHA512 maximal nutzen. Daher liegt der Peak bei 78 Zeichen.
Lassen Sie mich das noch einmal sagen. Für diese Klasse von Passwörtern können Sie nur weitere 6 Zeichen speichern, bevor Ihnen die Entropie ausgeht.
Nicht zufällige Passwörter mit niedriger Entropie
Dies ist die Gruppe, die alphanumerische Zeichen verwendet, die wahrscheinlich nicht zufällig generiert werden. So etwas wie ein Bibelzitat oder so. Diese Phrasen haben ungefähr 2,3 Bit Entropie pro Zeichen.
Für diese Gruppe können Sie durch Hashing erheblich mehr Entropie freischalten (nicht erstellen, sondern mehr in die Eingabe des bcrypt-Kennworts einfügen). Die Gewinnschwelle liegt bei 223 Zeichen, bevor Ihnen die Entropie ausgeht.
Sagen wir das noch einmal. Für diese Klasse von Passwörtern erhöht das Pre-Hashing die Sicherheit definitiv erheblich.
Zurück in die reale Welt
Diese Art von Entropieberechnungen spielt in der realen Welt keine große Rolle. Was zählt, ist das Erraten der Entropie. Das wirkt sich direkt auf das aus, was Angreifer tun können. Das möchten Sie maximieren.
Während es wenig Forschung gibt, die sich mit dem Erraten von Entropie befasst, gibt es einige Punkte, auf die ich hinweisen möchte.
Die Wahrscheinlichkeit, 72 richtige Zeichen hintereinander zufällig zu erraten, ist äußerst gering. Es ist wahrscheinlicher, dass Sie 21 Mal die Powerball-Lotterie gewinnen, als dass Sie diese Kollision haben ... So groß ist die Zahl, über die wir sprechen.
Aber wir dürfen statistisch nicht darüber stolpern. Bei Phrasen ist die Wahrscheinlichkeit, dass die ersten 72 Zeichen gleich sind, viel höher als bei einem zufälligen Passwort. Aber es ist immer noch trivial niedrig (es ist wahrscheinlicher, dass Sie die Powerball-Lotterie fünfmal gewinnen, basierend auf 2,3 Bit pro Charakter).
Praktisch
Praktisch ist es nicht wirklich wichtig. Die Wahrscheinlichkeit, dass jemand die ersten 72 Zeichen richtig errät, wobei letztere einen signifikanten Unterschied machen, ist so gering, dass es sich nicht lohnt, sich Sorgen zu machen. Warum?
Nehmen wir an, Sie nehmen einen Satz. Wenn die Person die ersten 72 Zeichen richtig machen kann, hat sie entweder wirklich Glück (nicht wahrscheinlich) oder es ist eine übliche Phrase. Wenn es sich um eine gebräuchliche Phrase handelt, ist die einzige Variable, wie lange sie benötigt wird.
Nehmen wir ein Beispiel. Nehmen wir ein Zitat aus der Bibel (nur weil es eine häufige Quelle für Langtext ist, nicht aus irgendeinem anderen Grund):
Das sind 180 Zeichen. Das 73. Zeichen ist das
g
im zweitenneighbor's
. Wenn Sie so viel erraten haben, werden Sie wahrscheinlich nicht vorbeischauennei
, sondern mit dem Rest des Verses fortfahren (da das Passwort wahrscheinlich so verwendet wird). Daher hat Ihr "Hash" nicht viel hinzugefügt.Übrigens: Ich befürworte ABSOLUT NICHT, ein Bibelzitat zu verwenden. In der Tat das genaue Gegenteil.
Fazit
Sie werden Menschen, die lange Passwörter verwenden, nicht wirklich helfen, indem Sie zuerst Hashing durchführen. Bei einigen Gruppen kann man definitiv helfen. Einige kann man definitiv verletzen.
Aber am Ende ist nichts davon übermäßig bedeutsam. Die Zahlen , die wir es zu tun sind nur WAY zu hoch. Der Unterschied in der Entropie wird nicht groß sein.
Sie sollten bcrypt besser so lassen, wie es ist. Es ist wahrscheinlicher, dass Sie das Hashing vermasseln (im wahrsten Sinne des Wortes, Sie haben es bereits getan, und Sie sind nicht der erste oder letzte, der diesen Fehler macht), als dass der Angriff, den Sie verhindern möchten, stattfinden wird.
Konzentrieren Sie sich auf die Sicherung des restlichen Standorts. Fügen Sie bei der Registrierung ein Kennwortentropiemessgerät in das Kennwortfeld ein, um die Kennwortstärke anzuzeigen (und geben Sie an, ob ein Kennwort zu lang ist, das der Benutzer möglicherweise ändern möchte) ...
Das sind mindestens meine $ 0,02 (oder möglicherweise weit mehr als $ 0,02) ...
Soweit die Verwendung eines "geheimen" Pfeffers:
Es gibt buchstäblich keine Forschung darüber, wie man eine Hash-Funktion in bcrypt einspeist. Daher ist es bestenfalls unklar, ob das Einspeisen eines "gepfefferten" Hashs in bcrypt jemals unbekannte Sicherheitslücken verursachen wird (wir wissen, dass dies
hash1(hash2($value))
erhebliche Sicherheitslücken in Bezug auf Kollisionsresistenz und Preimage-Angriffe aufdecken kann).Wenn Sie bereits überlegen, einen geheimen Schlüssel (den "Pfeffer") aufzubewahren, sollten Sie ihn auf eine Weise verwenden, die gut studiert und verstanden ist. Warum nicht den Hash verschlüsseln, bevor er gespeichert wird?
Nachdem Sie das Kennwort gehasht haben, geben Sie die gesamte Hash-Ausgabe in einen starken Verschlüsselungsalgorithmus ein. Speichern Sie dann das verschlüsselte Ergebnis.
Jetzt wird bei einem SQL-Injection-Angriff nichts Nützliches verloren gehen, da sie nicht über den Chiffrierschlüssel verfügen. Und wenn der Schlüssel durchgesickert ist, sind die Angreifer nicht besser dran als wenn Sie einen einfachen Hash verwendet haben (was nachweislich etwas mit dem Pfeffer "Pre-Hash" nicht bietet).
Hinweis: Wenn Sie sich dazu entscheiden, verwenden Sie eine Bibliothek. Für PHP empfehle ich dringend das
Zend\Crypt
Paket von Zend Framework 2 . Es ist tatsächlich das einzige, das ich zu diesem Zeitpunkt empfehlen würde. Es wurde stark überprüft und trifft alle Entscheidungen für Sie (was eine sehr gute Sache ist) ...Etwas wie:
Und es ist vorteilhaft, weil Sie alle Algorithmen auf eine Weise verwenden, die gut verstanden und gut untersucht ist (zumindest relativ). Merken:
quelle
Das Peppen von Passwörtern ist sicherlich eine gute Sache, aber mal sehen warum.
Zuerst sollten wir die Frage beantworten, wann genau ein Pfeffer hilft. Der Pfeffer schützt nur die Passwörter, solange er geheim bleibt. Wenn ein Angreifer also Zugriff auf den Server selbst hat, ist er nutzlos. Ein viel einfacherer Angriff ist jedoch die SQL-Injection, die den Lesezugriff auf die Datenbank (auf unsere Hash-Werte) ermöglicht. Ich habe eine Demo der SQL-Injection vorbereitet, um zu zeigen, wie einfach es sein kann (klicken Sie auf den nächsten Pfeil, um eine Vorbereitung zu erhalten Eingang).
Was hilft dann der Pfeffer eigentlich? Solange der Pfeffer geheim bleibt, schützt er schwache Passwörter vor einem Wörterbuchangriff. Das Passwort
1234
würde dann so etwas wie werden1234-p*deDIUZeRweretWy+.O
. Dieses Passwort ist nicht nur viel länger, es enthält auch Sonderzeichen und wird niemals Teil eines Wörterbuchs sein.Jetzt können wir abschätzen, welche Passwörter unsere Benutzer verwenden werden. Wahrscheinlich geben mehr Benutzer schwache Passwörter ein, da es Benutzer mit Passwörtern zwischen 64 und 72 Zeichen gibt (tatsächlich ist dies sehr selten).
Ein weiterer Punkt ist der Bereich für Brute-Forcing. Die sha256-Hash-Funktion gibt 256-Bit-Ausgabe oder 1.2E77-Kombinationen zurück, das ist viel zu viel für Brute-Forcing, selbst für GPUs (wenn ich richtig berechnet habe, würde dies auf einer GPU im Jahr 2013 ungefähr 2E61 Jahre dauern ). Wir bekommen also keinen wirklichen Nachteil beim Auftragen des Pfeffers. Da die Hash-Werte nicht systematisch sind, können Sie das Brute-Forcing nicht mit gängigen Mustern beschleunigen.
PS Soweit ich weiß, ist die Beschränkung auf 72 Zeichen spezifisch für den Algorithmus von BCrypt. Die beste Antwort, die ich gefunden habe, ist diese .
PPS Ich denke, Ihr Beispiel ist fehlerhaft. Sie können den Hash nicht mit der vollen Kennwortlänge generieren und mit einem abgeschnittenen überprüfen. Sie wollten den Pfeffer wahrscheinlich auf die gleiche Weise anwenden, um den Hash zu generieren und den Hash zu überprüfen.
quelle
true
. Darum geht es in dieser Frage. Schauen Sie selbst: viper-7.com/RLKFnBBcrypt verwendet einen Algorithmus, der auf dem teuren Blowfish-Schlüssel-Setup-Algorithmus basiert.
Das empfohlene 56-Byte-Passwortlimit (einschließlich Nullterminierungsbyte) für bcrypt bezieht sich auf das 448-Bit-Limit des Blowfish-Schlüssels. Alle Bytes, die über diese Grenze hinausgehen, werden nicht vollständig in den resultierenden Hash gemischt. Das absolute Limit von 72 Byte für bcrypt-Passwörter ist daher weniger relevant, wenn Sie die tatsächliche Auswirkung dieser Bytes auf den resultierenden Hash berücksichtigen.
Wenn Sie der Meinung sind, dass Ihre Benutzer normalerweise Kennwörter mit einer Länge von mehr als 55 Byte auswählen würden, denken Sie daran, dass Sie stattdessen immer die Runden der Kennwortverlängerung erhöhen können, um die Sicherheit im Falle einer Verletzung der Kennworttabelle zu erhöhen (obwohl dies im Vergleich zum Hinzufügen zusätzlicher Kennwörter sehr viel sein muss Zeichen). Wenn die Zugriffsrechte der Benutzer so kritisch sind, dass Benutzer normalerweise ein sehr langes Kennwort benötigen, sollte der Ablauf des Kennworts ebenfalls kurz sein, z. B. 2 Wochen. Dies bedeutet, dass ein Passwort mit viel geringerer Wahrscheinlichkeit gültig bleibt, während ein Hacker seine Ressourcen in die Überwindung des Arbeitsfaktors investiert, der beim Testen jedes Testpassworts erforderlich ist, um festzustellen, ob es einen passenden Hash erzeugt.
Wenn die Kennworttabelle nicht verletzt wird, sollten wir Hackern natürlich höchstens zehn Versuche erlauben, das 55-Byte-Kennwort eines Benutzers zu erraten, bevor das Benutzerkonto gesperrt wird;)
Wenn Sie ein Kennwort vorab hashen, das länger als 55 Byte ist, sollten Sie SHA-384 verwenden, da es die größte Ausgabe hat, ohne das Limit zu überschreiten.
quelle