web-dev-qa-db-de.com

Welcher Datentyp für das Hash-Passwort-Feld und welche Länge?

Ich bin nicht sicher, wie Passwort-Hashing funktioniert (wird später implementiert), muss aber jetzt ein Datenbankschema erstellen.

Ich denke an die Begrenzung von Passwörtern auf 4-20 Zeichen, aber wie ich verstehe, wird der Hash-String nach dem Verschlüsseln eine andere Länge haben.

Wie speichert man diese Passwörter in der Datenbank?

257
z-boss

Update: Die einfache Verwendung einer Hash-Funktion ist nicht stark genug, um Passwörter zu speichern. Sie sollten die Antwort von Gilles zu diesem Thread lesen, um eine genauere Erklärung zu erhalten.

Verwenden Sie für Kennwörter einen Schlüsselverstärkungs-Hash-Algorithmus wie Bcrypt oder Argon2i. Verwenden Sie beispielsweise in PHP die Funktion password_hash () , die standardmäßig Bcrypt verwendet.

$hash = password_hash("rasmuslerdorf", PASSWORD_DEFAULT);

Das Ergebnis ist eine 60-stellige Zeichenfolge, die der folgenden ähnelt (die Ziffern variieren jedoch, da ein eindeutiges Salt generiert wird).

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

Verwenden Sie den SQL-Datentyp CHAR(60), um diese Codierung eines Bcrypt-Hashs zu speichern. Beachten Sie, dass diese Funktion nicht als hexadezimale Zeichenfolge codiert wird. Wir können sie daher nicht so einfach enthexen, um sie im Binärformat zu speichern.

Andere Hash-Funktionen werden weiterhin verwendet, jedoch nicht zum Speichern von Kennwörtern. Daher behalte ich die ursprüngliche Antwort aus dem Jahr 2008 bei.


Dies hängt vom verwendeten Hashing-Algorithmus ab. Das Hashing erzeugt unabhängig von der Eingabe immer ein Ergebnis mit der gleichen Länge. Es ist typisch, das binäre Hash-Ergebnis in Text als eine Reihe hexadezimaler Ziffern darzustellen. Oder Sie können die Funktion UNHEX() verwenden, um eine Folge von Hexadezimalziffern um die Hälfte zu reduzieren.

  • MD5 generiert einen 128-Bit-Hashwert. Sie können CHAR (32) oder BINARY (16) verwenden
  • SHA-1 generiert einen 160-Bit-Hashwert. Sie können CHAR (40) oder BINARY (20) verwenden.
  • SHA-224 generiert einen 224-Bit-Hashwert. Sie können CHAR (56) oder BINARY (28) verwenden
  • SHA-256 generiert einen 256-Bit-Hashwert. Sie können CHAR (64) oder BINARY (32) verwenden.
  • SHA-384 generiert einen 384-Bit-Hashwert. Sie können CHAR (96) oder BINARY (48) verwenden.
  • SHA-512 generiert einen 512-Bit-Hashwert. Sie können CHAR (128) oder BINARY (64) verwenden.
  • BCrypt generiert einen implementierungsabhängigen 448-Bit-Hashwert. Möglicherweise benötigen Sie CHAR (56), CHAR (60), CHAR (76), BINARY (56) oder BINARY (60)

Ab 2015 NIST empfiehlt die Verwendung von SHA-256 oder höher für alle Anwendungen von Hash-Funktionen, die Interoperabilität erfordern. NIST rät jedoch davon ab, diese einfachen Hash-Funktionen zum sicheren Speichern von Kennwörtern zu verwenden.

Kleinere Hashing-Algorithmen haben ihre Verwendung (wie sie in einer Anwendung verwendet werden, nicht für den Austausch), aber sie sind bekanntermaßen knackbar .

440
Bill Karwin

Sie können CHAR (Länge des Hash) verwenden, um Ihren Datentyp für MySQL zu definieren, da jeder Hash-Algorithmus immer dieselbe Anzahl von Zeichen ergibt. Beispielsweise gibt SHA1 immer eine 40-stellige Hexadezimalzahl zurück.

13
Noah Goodrich

Vielleicht finden Sie diesen Wikipedia-Artikel zum Thema Salzen lohnenswert . Die Idee ist, ein bestimmtes Datenbit hinzuzufügen, um Ihren Hash-Wert zufällig zu sortieren. Dies schützt Ihre Passwörter vor Wörterbuchangriffen, wenn jemand nicht autorisierten Zugriff auf die Passwort-Hashes erhält.

8
Dana the Sane

Als Zeichenkette mit fester Länge (VARCHAR (n) oder wie auch immer MySQL es nennt). Ein Hash hat immer eine feste Länge von beispielsweise 12 Zeichen (abhängig von dem von Ihnen verwendeten Hash-Algorithmus). Ein 20-Zeichen-Passwort würde also auf einen 12-Zeichen-Hash reduziert, und ein 4-Zeichen-Passwort würde ebenfalls einen 12-Zeichen-Hash ergeben.

7
Treb

Verwenden Sie immer einen Passwort-Hashing-Algorithmus: Argon2 , Scrypt , Bcrypt oder PBKDF2 .

Argon2 hat den Passwort-Hashing-Wettbewerb 2015 gewonnen. Scrypt , bcrypt und PBKDF2 sind ältere Algorithmen, die derzeit als weniger bevorzugt angesehen werden, aber im Grunde immer noch solide sind. Wenn Ihre Plattform also Argon2 nicht unterstützt, Es ist jedoch in Ordnung, vorerst einen anderen Algorithmus zu verwenden.

Speichern Sie niemals ein Passwort direkt in einer Datenbank. Verschlüsseln Sie es auch nicht. Andernfalls erhält der Angreifer bei einem Verstoß gegen Ihre Website den Entschlüsselungsschlüssel und kann so alle Kennwörter abrufen. Passwörter MÜSSEN gehasht sein.

Ein Passwort-Hash hat andere Eigenschaften als ein Hash-Tabellen-Hash oder ein kryptografischer Hash. Verwenden Sie niemals einen gewöhnlichen kryptografischen Hash wie MD5, SHA-256 oder SHA-512 für ein Kennwort. Ein Passwort-Hashing-Algorithmus verwendet ein salt, das eindeutig ist (nicht für einen anderen Benutzer oder in der Datenbank eines anderen Benutzers verwendet). Das Salt ist notwendig, damit Angreifer die Hashes gängiger Passwörter nicht einfach vorberechnen können: Mit einem Salt müssen sie die Berechnung für jedes Konto neu starten. Ein Passwort-Hashing-Algorithmus ist an sich langsam - so langsam, wie Sie es sich leisten können. Langsamkeit schmerzt den Angreifer viel mehr als Sie, weil der Angreifer viele verschiedene Passwörter ausprobieren muss. Weitere Informationen finden Sie unter Sicheres Hashing von Kennwörtern .

Ein Passwort-Hash verschlüsselt vier Informationen:

  • Ein Indikator, welcher Algorithmus verwendet wird. Dies ist notwendig für Agilität : Kryptografische Empfehlungen ändern sich mit der Zeit. Sie müssen in der Lage sein, auf einen neuen Algorithmus umzusteigen.
  • Ein Schwierigkeits- oder Härteindikator. Je höher dieser Wert ist, desto mehr Berechnungen sind erforderlich, um den Hash zu berechnen. Dies sollte eine Konstante oder ein globaler Konfigurationswert in der Kennwortänderungsfunktion sein, der jedoch mit der Zeit zunimmt, wenn Computer schneller werden. Sie müssen sich daher den Wert für jedes Konto merken. Einige Algorithmen haben einen einzelnen numerischen Wert, andere haben dort mehr Parameter (zum Beispiel, um die CPU-Auslastung zu optimieren und RAM Auslastung separat)).
  • Das Salz. Da das Salz global eindeutig sein muss, muss es für jedes Konto gespeichert werden. Das Salt sollte bei jeder Passwortänderung zufällig generiert werden.
  • Der eigentliche Hash, d. H. Die Ausgabe der mathematischen Berechnung im Hashing-Algorithmus.

Viele Bibliotheken enthalten Paarfunktionen, die diese Informationen bequem als einzelne Zeichenfolge zusammenfassen: eine, die den Algorithmusindikator, den Härteindikator und das Kennwort verwendet, ein zufälliges Salt generiert und die vollständige Hash-Zeichenfolge zurückgibt; und eine, die ein Kennwort und die vollständige Hash-Zeichenfolge als Eingabe verwendet und einen Booleschen Wert zurückgibt, der angibt, ob das Kennwort korrekt war. Es gibt keinen universellen Standard, aber eine übliche Kodierung ist

$  Algorithmus $  Parameter $  Salz $  Ausgabe

wobei algorithm eine Zahl oder eine kurze alphanumerische Zeichenfolge ist, die die Wahl des Algorithmus codiert, parameters eine druckbare Zeichenfolge ist und salt und output in Base64 codiert sind ohne = zu beenden.

16 Bytes reichen für das Salt und die Ausgabe. (Siehe z. B. Empfehlungen für Argon2 .) In Base64 sind das jeweils 21 Zeichen. Die anderen beiden Teile hängen vom Algorithmus und den Parametern ab, aber 20 bis 40 Zeichen sind typisch. Das sind insgesamt ungefähr 82 ASCII Zeichen (CHAR(82) und keine Notwendigkeit für Unicode) , zu dem Sie einen Sicherheitsabstand hinzufügen sollten, wenn Sie der Meinung sind, dass es schwierig sein wird, das Feld später zu vergrößern.

Wenn Sie den Hash in einem Binärformat codieren, können Sie ihn für den Algorithmus auf 1 Byte, für die Härte auf 1 bis 4 Byte (wenn Sie einige Parameter hart codieren) und für Salt und Output auf jeweils 16 Byte reduzieren für insgesamt 37 Bytes. Sagen Sie 40 Bytes (BINARY(40)), um mindestens ein paar Ersatzbytes zu haben. Beachten Sie, dass dies 8-Bit-Bytes und keine druckbaren Zeichen sind. Insbesondere kann das Feld Null-Bytes enthalten.

Beachten Sie, dass die Länge des Hash völlig unabhängig von der Länge des Passworts ist.

5
Gilles

Es hängt wirklich vom verwendeten Hashing-Algorithmus ab. Die Länge des Passworts hat wenig mit der Länge des Hashes zu tun, wenn ich mich richtig erinnere. Schlagen Sie die Spezifikationen des von Ihnen verwendeten Hashing-Algorithmus nach, führen Sie einige Tests durch und kürzen Sie sie direkt darüber.

3
willasaywhat

Hashes sind eine Folge von Bits (128 Bits, 160 Bits, 256 Bits usw., abhängig vom Algorithmus). Ihre Spalte sollte vom Typ Binär sein und nicht vom Typ Text/Zeichen, wenn MySQL dies zulässt (SQL Server-Datentyp ist binary(n) oder varbinary(n)). Sie sollten auch die Hashes salzen. Salze können Text oder Binär sein, und Sie benötigen eine entsprechende Spalte.

3
yfeldblum

Sie sollten aus Gründen der Aufwärtskompatibilität TEXT (Speichern einer unbegrenzten Anzahl von Zeichen) verwenden. Hashing-Algorithmen werden mit der Zeit immer leistungsfähiger und daher muss dieses Datenbankfeld mit der Zeit mehr Zeichen unterstützen. Außerdem müssen Sie abhängig von Ihrer Migrationsstrategie möglicherweise neue und alte Hashes im selben Feld speichern, sodass es nicht empfehlenswert ist, die Länge auf eine Art von Hash zu beschränken.

3
bart

Ich habe immer versucht, die MAX-Zeichenfolgenlänge einer verschlüsselten Zeichenfolge zu ermitteln und diese als Zeichenlänge eines VARCHAR-Typs festzulegen. Abhängig davon, wie viele Datensätze Sie haben werden, kann dies die Datenbankgröße erheblich verbessern.

1
Stephen Walcher

für md5 ist vARCHAR (32) angemessen. Für diejenigen, die AES verwenden, ist es besser, Varbinary zu verwenden.

0
Hare Srinivasa