wake-up-neo.com

Welchen Spaltentyp / welche Spaltenlänge sollte ich zum Speichern eines Bcrypt-Hash-Passworts in einer Datenbank verwenden?

Ich möchte ein gehashtes Passwort (mit BCrypt) in einer Datenbank speichern. Was wäre ein guter Typ dafür und welche wäre die richtige Länge? Sind mit BCrypt gehashte Passwörter immer gleich lang?

[~ # ~] edit [~ # ~]

Beispiel Hash:

$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu

Nach dem Hashing einiger Passwörter scheint BCrypt immer 60 Zeichen-Hashes zu generieren.

EDIT 2

Entschuldigung, dass Sie die Implementierung nicht erwähnt haben. Ich benutze jBCrypt .

286
helpermethod

Das modulare Kryptoformat für bcrypt besteht aus

  • $2$, $2a$ Oder $2y$, Die den Hashalgorithmus und -format identifizieren
  • ein zweistelliger Wert, der den Kostenparameter angibt, gefolgt von $
  • ein 53 Zeichen langer Base-64-codierter Wert (sie verwenden das Alphabet ., /, 0 - 9, AZ, az, das sich vom Standard Base 64 Encoding Alphabet unterscheidet, bestehend aus:
    • 22 Zeichen Salz (effektiv nur 128 Bits der 132 dekodierten Bits)
    • 31 Zeichen verschlüsselte Ausgabe (effektiv nur 184 Bits der 186 decodierten Bits)

Somit beträgt die Gesamtlänge 59 bzw. 60 Bytes.

Wenn Sie das 2a-Format verwenden, benötigen Sie 60 Byte. Und deshalb empfehle ich für MySQL die Verwendung von CHAR(60) BINARY oder BINARY(60) (siehe The _ bin und binäre Kollatierungen zur Information über den Unterschied).

CHAR ist nicht binär sicher und die Gleichheit hängt nicht nur vom Byte-Wert ab, sondern auch von der tatsächlichen Sortierung. im schlimmsten Fall wird A gleich a behandelt. Weitere Informationen finden Sie unter Die Kollatierungen _bin Und binary .

339
Gumbo

Ein Bcrypt-Hash kann in einer BINARY(40) -Spalte gespeichert werden.

BINARY(60) ist, wie die anderen Antworten andeuten, die einfachste und natürlichste Wahl. Wenn Sie jedoch die Speichereffizienz maximieren möchten, können Sie 20 Byte einsparen, indem Sie den Hash verlustfrei dekonstruieren. Ich habe dies auf GitHub genauer dokumentiert: https: //github.com/ademarre/binary-mcf

Bcrypt-Hashes folgen einer Struktur, die als modulares Crypt-Format (MCF) bezeichnet wird. Binär MCF (BMCF) decodiert diese textuellen Hash-Darstellungen in eine kompaktere Binärstruktur. Im Fall von Bcrypt beträgt der resultierende binäre Hash 40 Bytes.

Gumbo hat die vier Komponenten eines Bcrypt-MCF-Hashes sehr gut erklärt:

$<id>$<cost>$<salt><digest>

Das Dekodieren in BMCF geht so:

  1. $<id>$ kann in 3 Bits dargestellt werden.
  2. <cost>$, 04-31, kann in 5 Bits dargestellt werden. Fügen Sie diese für 1 Byte zusammen.
  3. Das 22-stellige Salt ist eine (nicht standardmäßige) Base-64-Darstellung von 128 Bit. Die Base-64-Decodierung ergibt 16 Bytes.
  4. Der 31-stellige Hash-Digest kann zur Basis 64 in 23 Bytes dekodiert werden.
  5. Alles zusammen für 40 Bytes: 1 + 16 + 23

Sie können mehr unter dem obigen Link lesen oder my PHP Implementierung auch auf GitHub überprüfen.

48
Andre D

Wenn Sie PHP's password_hash() mit dem Algorithmus PASSWORD_DEFAULT Verwenden, um den bcrypt-Hash zu generieren (von dem ich annehme, dass ein großer Prozentsatz der Leute, die diese Frage lesen, diese Frage lesen), müssen Sie sicherstellen, dass Sie sie behalten Beachten Sie, dass password_hash() in Zukunft möglicherweise einen anderen Algorithmus als Standard verwendet und dies daher die Länge des Hashs beeinflussen kann (aber nicht unbedingt länger sein muss).

Von der Manualseite:

Beachten Sie, dass sich diese Konstante im Laufe der Zeit ändern soll, wenn neue und leistungsfähigere Algorithmen zu PHP hinzugefügt werden. Aus diesem Grund kann sich die Länge des Ergebnisses aus der Verwendung dieses Bezeichners im Laufe der Zeit ändern. Daher wird empfohlen , das Ergebnis in einer Datenbankspalte zu speichern, die über 60 Zeichen hinausgehen kann (255 Zeichen wären eine gute Wahl).

Selbst wenn Sie mit bcrypt 1 Milliarde Benutzer haben (d. H. Sie konkurrieren derzeit mit Facebook), um 255-Byte-Passwort-Hashes zu speichern, wären es nur ~ 255 GB Daten - etwa die Größe einer kleinen SSD-Festplatte. Es ist äußerst unwahrscheinlich, dass das Speichern des Kennwort-Hashs den Engpass in Ihrer Anwendung darstellt. Wenn jedoch die Möglichkeit besteht, dass der Speicherplatz tatsächlich ein Problem darstellt , können Sie PASSWORD_BCRYPT Verwenden, um password_hash() zu erzwingen. um bcrypt zu verwenden, auch wenn dies nicht die Standardeinstellung ist. Achten Sie jedoch darauf, über alle in bcrypt gefundenen Schwachstellen auf dem Laufenden zu bleiben, und lesen Sie die Versionshinweise jedes Mal durch, wenn eine neue PHP version veröffentlicht wird. Wenn der Standardalgorithmus jemals geändert wird, ist es hilfreich, warum und eine fundierte Entscheidung treffen, ob der neue Algorithmus verwendet werden soll oder nicht.

21
Mike

Ich glaube nicht, dass es irgendwelche netten Tricks gibt, mit denen Sie das speichern können, wie Sie es zum Beispiel mit einem MD5-Hash tun können.

Ich denke, Ihre beste Wette ist es, es als CHAR(60) zu speichern, da es immer 60 Zeichen lang ist

18
James C