Ich habe Beispiele für Passwort-Hashing gesehen, die waren: H (Benutzername + Salt + Passwort). Was ist der Zweck des Hinzufügens eines Benutzernamens? Gibt es einen Zweck?
Ich habe Beispiele für Passwort-Hashing gesehen, die waren: H (Benutzername + Salt + Passwort). Was ist der Zweck des Hinzufügens eines Benutzernamens? Gibt es einen Zweck?
Nein, es gibt keinen Zweck. Das ist Sicherheitstheater *. Der Zweck eines Salzes besteht darin, parallele Angriffe auf alle gehashten Passwörter unmöglich zu machen und Regenbogentabellen zu brechen. Durch Hinzufügen des Benutzernamens wird dieses Verhalten nicht verbessert oder andere Sicherheitsaspekte erhöht. Es hat tatsächlich einen kleinen Nachteil, da Sie jetzt auf einige Probleme stoßen, wenn Sie den Benutzernamen ändern und ein komplexeres und nicht standardmäßiges System warten müssen. In einem rein kryptografischen Sinne gibt es keinen Nachteil. In der Praxis bedeutet mehr Komplexität jedoch mehr Fehler.
Sie könnten denken, dass der Benutzername selbst möglicherweise nicht öffentlich ist, sodass die Verwendung nicht schaden kann Es ist ein zusätzliches Geheimnis, aber Tatsache ist, dass die Datenbank wahrscheinlich bereits den Benutzernamen im Klartext enthält, was diesen bereits fragwürdigen Vorteil ungültig macht. Die Benutzer sollten sich an bereits vorhandene Authentifizierungstechniken halten. Aber schauen wir uns die Eigenschaften jedes dieser Objekte an:
Ein Salz ist:
Nicht geheim - Salze werden im Klartext gespeichert.
Sicher - Sie werden zufällig generiert und sind lang.
Einzigartig - Das Salz jedes Benutzers ist absichtlich anders.
Ein Passwort lautet:
Geheimnis - Angenommen, sie werden nicht auf eine Haftnotiz gesetzt.
Sicher - Wenn es nicht hunter2 ist. Das Passwort sollte gut sein.
Eindeutig - Zumindest im Idealfall, aber nicht alle Passwörter sind ideal.
Vergleichen Sie dies nun mit einem Benutzernamen. Ein Benutzername lautet:
Nicht geheim - Sie sind öffentlich oder zumindest im Klartext gespeichert.
Nicht sicher - Niemand denkt daran, einen langen und komplexen Benutzernamen zu wählen.
Nicht eindeutig - Benutzernamen können sicher zwischen Websites geteilt werden.
Nun, was genau macht ein Salz? Im Allgemeinen bietet ein gutes Salz drei Vorteile:
Es verhindert, dass ein Angreifer den Hash jedes Benutzers gleichzeitig angreift. Der Angreifer kann ein Kandidatenkennwort nicht mehr hashen und es für jeden einzelnen Eintrag gleichzeitig testen. Sie sind gezwungen, ein bestimmtes Kennwort neu zu berechnen, um es für den Hash jedes Benutzers zu testen. Dieser Vorteil, den ein Salz bietet, wächst linear, wenn die Anzahl der unterschiedlichen Ziel-Hash-Einträge zunimmt. Natürlich sind Salze immer noch wichtig, auch wenn nur ein einziger Hash geschützt werden muss, wie ich weiter unten erläutere.
Dies macht Regenbogentabellen unmöglich . Eine Regenbogentabelle ist eine hochoptimierte vorberechnete Tabelle, die Kennwörter mit Hashes vergleicht. Sie benötigen weniger Platz als eine gigantische Nachschlagetabelle, benötigen jedoch viel Zeit zum Generieren (ein Raum-Zeit-Kompromiss ). Damit Regenbogentabellen funktionieren, muss ein bestimmtes Kennwort immer in denselben Hash aufgelöst werden. Salze brechen diese Annahme und machen Regenbogentabellen unpraktisch, da sie für jedes mögliche Salz einen neuen Eintrag benötigen würden.
Es verhindert gezielte Vorberechnung durch Regenbogentabellen, zumindest wenn der Hash wirklich zufällig ist. Ein Angreifer kann den Angriff erst beginnen, nachdem er die Hashes (und mit ihnen die Salze) in die Hände bekommen hat. Wenn das Salz bereits öffentlich ist, der Hash jedoch nicht, kann der Angriff optimiert werden, indem eine Regenbogentabelle für dieses bestimmte Salz erstellt wird. Dies ist ein Grund, warum WPA2 ein so hässliches Protokoll ist. Das Salz ist die ESSID (Netzwerkname), sodass jemand den Angriff für den Router seines Ziels starten kann, bevor er überhaupt den 4-Wege-Handshake in die Hände bekommt.
Welchen möglichen Vorteil hätte es also, einen Wert vor dem Hashing zu verketten, wenn dieser Wert öffentlich, unsicher und wiederverwendet ist? Der Angreifer muss nicht nach weiteren Informationen suchen. Es trägt nicht zur Sicherheit eines Salzes bei. Dies erhöht nicht die Komplexität des Passworts. Es gibt keinen Vorteil.
Also was sollen sie tun, um die Sicherheit zu erhöhen? Sie können anstelle eines einzelnen Hashs ein KDF wie PBKDF2, bcrypt, scrypt oder argon2 verwenden. Sie können einen Pfeffer hinzufügen, bei dem es sich um einen zufälligen globalen Wert handelt, der außerhalb der Datenbank gespeichert und dem Kennwort und dem Salz hinzugefügt wird. Daher muss der Pfeffer gestohlen werden, um zu versuchen, die Hashes anzugreifen, anstatt ihn einfach zu entleeren Datenbank mit SQLi.
BEARBEITEN: Wie einige Kommentare hervorheben, gibt es ein erfundenes Szenario, in dem der Benutzername hilfreich wäre, um ihn in die Mischung aufzunehmen. In diesem Szenario ist die Implementierung so stark fehlerhaft, dass das Salt eigentlich kein Salt ist und der Benutzername der einzige eindeutige oder halb eindeutige Wert pro Benutzer in der Datenbank ist. In diesem Fall wäre es besser, den Benutzernamen einzumischen als nichts. Aber wirklich, wenn Sie kein Salz haben, sollten Sie anfangen, einen zu verwenden, anstatt zu versuchen, Benutzernamen zu verwenden. Verwenden Sie echte Sicherheit und seien Sie nicht halbherzig, wenn die Sicherheit Ihrer Benutzer auf dem Spiel steht.
* In diesem Zusammenhang definiere ich Sicherheitstheater als die Praxis, Sicherheitsmaßnahmen zu implementieren, die dies tun die Sicherheit in keiner sinnvollen Weise verbessern und nur vorhanden sein, um die Illusion einer besseren Sicherheit zu vermitteln. sub>
Wenn das Salz so zufällig ist, wie es sein soll, bietet das Hinzufügen des Benutzernamens keinen zusätzlichen Schutz. Es verursacht aber auch keinen Schaden, abgesehen davon, dass der Code komplexer wird, was die Wahrscheinlichkeit von Fehlern erhöht. Wenn Sie eine Codeüberprüfung durchführen, kann dies als Zeichen dafür verstanden werden, dass der Entwickler nicht vollständig versteht, was er tut.
Wenn das Salt stattdessen größtenteils statisch ist oder vom Kennwort abgeleitet wird, kann der Benutzername seitdem hilfreich sein In diesem Fall dient der Benutzername im Wesentlichen dem Zweck, den das Salz nicht erfüllt hat. Dies ist jedoch nicht der empfohlene Weg, da das Salz zufällig sein soll und ein Benutzername nicht.
Siehe Ist es eine gute Idee, den Benutzernamen des Benutzers als Salt zu verwenden, wenn ein Passwort wie Hash (Benutzername_str + Passwort_str) gehasht wird? und Was sollte als verwendet werden? Salz? für eine eingehendere Diskussion darüber, was ein gutes Salz sein sollte und warum der Benutzername kein gutes Salz ist. Siehe auch Warum sind gesalzene Hashes für die Kennwortspeicherung sicherer?, um den Zweck des Salt überhaupt zu verstehen.
Wie @Damien_The_Unbeliever in einem Kommentar hervorhob, kann dies den Identitätswechsel des Benutzers in einem Szenario verhindern, in dem das System teilweise kompromittiert wurde.
Stellen Sie sich das folgende Szenario vor. Irgendwie hat ein Angreifer Lese- / Schreibzugriff auf die für die Anmeldung verwendete DB-Tabelle erhalten, die Benutzernamen, Kennwort-Hashes und Salze enthält - möglicherweise über einen SQL-Injection-Angriff. Dieser Angreifer hat keinen anderen erhöhten Zugriff auf das System, möchte sich jedoch als Benutzer im System auf nicht nachvollziehbare (oder schwer nachvollziehbare) Weise ausgeben.
In einigen Systemen kann ein Angreifer mit dieser Zugriffsebene einfach einen Kennwort-Hash mit dem Benutzernamen, dem Salt und einem beliebigen Kennwort des Opfers generieren (anstatt sein eigenes zu kopieren). Dies ist jedoch nicht möglich, wenn der Das System verwendet zusätzlich zum Salz einen Pfeffer (eine global definierte Konstante, die der Eingabe für alle Passwort-Hashes hinzugefügt wird an einem anderen Ort als dem Passwort gespeichert (Hashes und Salze). Ohne den Pfeffer zu gefährden, kann der Angreifer in diesem Szenario einen Kennwort-Hash mit einem bekannten Kennwort für das Opfer nur festlegen, indem er einen vom System generierten Kennwort kopiert, wie oben beschrieben.
Beachten Sie diesen Zwei-Faktor Die Authentifizierung kann dies wahrscheinlich nicht einmal verhindern. Wenn der Angreifer auch Zugriff auf die 2FA-Initialisierungscodes für Benutzer hat (möglicherweise in derselben Datenbank-Tabelle gespeichert), kann der Code des Angreifers auch vorübergehend in das Konto des Opfers geschrieben werden.
Wenn im Gegensatz dazu der Benutzername für die Berechnung des Kennwort-Hash verwendet wird, funktioniert dieser bestimmte Identitätswechselangriff nicht. Selbst wenn der Angreifer seinen Passwort-Hash, Salt und 2FA-Code in das Konto des Opfers kopiert, führt die Verwendung des Passworts des Angreifers auf dem Konto des Opfers nicht zum gleichen Passwort-Hash wie für das Konto des Angreifers, sodass die Anmeldung fehlschlägt.
Es ist fraglich, ob die Vorteile die zusätzliche Komplexität und die Möglichkeit von Fehlern wert sind, da dieses Szenario erfordert, dass der Angreifer das System bereits ernsthaft kompromittiert hat, und in diesem Szenario stellt der Angreifer das tatsächliche des Benutzers nicht wieder her Passwort. Es kann jedoch argumentiert werden, dass dies ein zusätzlicher Schutz ist.
Für den Anfang sollte das Passwort-Hashing mit einer dedizierten Passwort-Hashing-Funktion wie bcrypt, Argon2, scrypt oder PBKDF2 durchgeführt werden. In diesem Fall müssen Sie das Salt und das Passwort nicht wie ein Grundelement verketten. Die Funktion verwendet diese als separate Argumente. Siehe "Wie man Passwörter sicher hasht?", eine der Top-Q&As auf dieser Site für dieses Thema.
Der Zweck des Salt beim Passwort-Hashing ist die Randomisierung die Hash-Funktion, die auf jeden Passworteintrag angewendet wird. Drei Regeln, die im Allgemeinen für moderne spezialisierte Passwort-Hashes gelten, sind folgende:
Jetzt können wir Ihre Frage beantworten, indem wir folgende Beobachtungen machen: