it-swarm.com.de

Warum sollte man Salt einen Benutzernamen hinzufügen, bevor man ein Passwort hasht?

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?

78
PaintingInAir

Nein, es gibt keinen Zweck. Das ist Sicherheitstheater *. Der Zweck eines Salt besteht darin, parallele Angriffe auf alle gehashten Passwörter unmöglich zu machen und Rainbow-Tabellen 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.

Die Eigenschaften von Salzen und Benutzernamen

Sie könnten denken, dass der Benutzername selbst möglicherweise nicht öffentlich ist, so dass es nicht schaden könnte, ihn als zusätzliches Geheimnis zu verwenden. Tatsache ist jedoch, dass die Datenbank den Benutzernamen wahrscheinlich bereits 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 - Vorausgesetzt, sie werden nicht auf eine Haftnotiz gesetzt.

  • Sicher - Wenn nicht hunter2 . Das Passwort sollte gut sein.

  • Einzigartig - Zumindest im Idealfall, aber nicht alle Passwörter sind ideal.

Vergleichen Sie dies nun mit einem Benutzernamen. Ein Benutzername ist:

  • 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.

Die Eigenschaften eines guten Salzes

Nun was genau macht ein Salz ? Im Allgemeinen bietet ein gutes Salz drei Vorteile:

  1. Es verhindert, dass ein Angreifer den Hash jedes Benutzers gleichzeitig angreift . Der Angreifer ist nicht mehr in der Lage, ein Kandidatenkennwort zu hashen und es für jeden einzelnen Eintrag gleichzeitig zu 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.

  2. Es macht Regenbogentabellen unmöglich . A Rainbow-Tabelle 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 Rainbow-Tabellen 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.

  3. Es verhindert gezielt Vorberechnung durch Rainbow-Tabellen, 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 public ist, der Hash jedoch nicht, kann der Angriff optimiert werden, indem eine Regenbogentabelle für dieses bestimmte Salz generiert wird. Dies ist ein Grund, warum WPA2 ein so hässliches Protokoll ist. Das Salz ist die ESSID (Netzwerkname), also kann jemand den Angriff beginnen für den Router seines Ziels, 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 Dig benötigt keine weiteren Informationen. Es trägt nicht zur Sicherheit eines Salzes bei. Dies erhöht die Komplexität des Passworts nicht. Es gibt keinen Vorteil.

Richtiges Passwort-Hashing

Also was sollen sie tun, um die Sicherheit zu erhöhen ? Sie können ein KDF wie PBKDF2, bcrypt, scrypt oder argon2 anstelle eines einzelnen Hashs verwenden. Sie können ein Pfeffer hinzufügen, einen zufälligen globalen Wert, 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 einfach den Speicherauszug zu erstellen Datenbank mit SQLi.

BEARBEITEN: Wie einige Kommentare zeigen, gibt es ein erfundenes Szenario, in dem der Benutzername nützlich 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 verwenden Sie eines, 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 der Implementierung von Sicherheitsmaßnahmen, die die Sicherheit in keiner sinnvollen Weise verbessern und nur die Illusion einer besseren Sicherheit vermitteln.

152
forest

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. Bei einer Codeüberprüfung 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 Passwort abgeleitet wird, kann der Benutzername hilfreich sein, da in diesem Fall der Benutzername im Wesentlichen dem Zweck dient, den das Salt 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 Salt verwendet werden? für eine tiefere 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.

11
Steffen Ullrich

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.

  • Zunächst zeichnet der Angreifer den ursprünglichen Passwort-Hash und Salt für das Konto des Opfers auf.
  • Als nächstes registriert der Angreifer sein eigenes Konto und kopiert den Passwort-Hash und Salt von seinem Konto in das Konto des Opfers.
  • Jetzt kann sich der Angreifer mit dem eigenen Passwort des Angreifers beim Konto des Opfers anmelden.
  • Wenn der Angreifer fertig ist, stellt er den Passwort-Hash und das Salz des Opfers wieder her, was es dem Opfer erschwert, zu erkennen, was passiert ist.

Während in einigen Systemen ein Angreifer mit dieser Zugriffsebene einfach einen Kennwort-Hash unter Verwendung des Benutzernamens, des Salt und eines beliebigen Kennworts des Opfers generieren kann (anstatt sein eigenes zu kopieren), ist dies nicht möglich, wenn das System ein Pfeffer zusätzlich zum Salz (eine global definierte Konstante, die der Eingabe für alle Passwort-Hashes hinzugefügt wird und an einem anderen Ort als den Passwort-Hashes und -Salzen gespeichert wird). 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, dass die Zwei-Faktor-Authentifizierung dies wahrscheinlich nicht einmal verhindern kann. 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.

Im Gegensatz dazu funktioniert dieser bestimmte Identitätswechselangriff nicht, wenn der Benutzername für die Berechnung des Kennwort-Hash verwendet wird. 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 Kennwort des Benutzers nicht wieder her. Es kann jedoch argumentiert werden, dass dies ein zusätzlicher Schutz ist.

10
zacronos

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 werden Passwörter sicher gehasht?" , eine der wichtigsten Fragen und Antworten auf dieser Website zu diesem Thema.

Der Zweck des Salt beim Passwort-Hashing besteht darin, die Hash-Funktion, die auf jeden Passworteintrag angewendet wird, zufällig zu sortieren. Drei Regeln, die im Allgemeinen für moderne spezialisierte Passwort-Hashes gelten, sind folgende:

  1. Jedes Mal, wenn Sie ein neues Passwort registrieren, sollten Sie ein neues Salz generieren. (Beachten Sie, dass dies bedeutet, dass Sie, wenn ein Benutzer sein Kennwort ändert, ein neues Salt für dieses Kennwort generieren und das Salt für das alte nicht wiederverwenden sollten. Salze sind an den Status eines Kennwortdatenbankeintrags gebunden , nicht an Benutzer.)
  2. Der Wert des Salzes sollte unabhängig vom Passwort selbst sein. Die Kenntnis des Passworts sollte beim Erraten des Salzes keine Hilfe sein, da ein Angreifer dieses Wissen sonst zur Vorberechnung einer Angriffstabelle verwenden könnte. Ein offensichtliches Beispiel hierfür ist, dass Sie das Passwort selbst nicht als Salz verwenden sollten. (Das ist weniger dumm, als es sich anhört - in diesem Fall würden Sie das Salz nicht neben dem Passwort speichern -, aber es ist dumm, weil zwei Benutzer mit das gleiche Passwort hätte den gleichen Hash.)
  3. Die Wahrscheinlichkeit, dass zwei Salze gleich sind, sollte sehr gering sein. Am besten nicht nur innerhalb Ihrer Anwendung, sondern weltweit auf der ganzen Welt.

Jetzt können wir Ihre Frage beantworten, indem wir folgende Beobachtungen machen:

  • Ein Salz, das aus einer ausreichenden Anzahl zufälliger Bytes besteht, erfüllt diese Kriterien bereits. 16 zufällige Bytes (von einem kryptografisch starken Zufallszahlengenerator) klingen sinnvoll.
  • Das Verketten des Benutzernamens mit einem solchen zufälligen Salz hilft nicht.
  • Wenn die Salze auf eine vorhersehbare, aber nicht wiederholte Weise generiert werden, z. B. als Zähler, der bei jeder Registrierung eines neuen Kennworts erhöht wird, oder als Zeitstempel, kann die Verkettung zusätzlicher Werte wie des Benutzernamens oder des Domainnamens Ihrer Site hilfreich sein es ist einzigartiger. Die Verwendung von zufälligen Salzen wäre jedoch einfacher (es ist nicht erforderlich, einen anhaltenden Gegenzustand im Auge zu behalten).
6
Luis Casillas