Warum erzeugt Crypt/Blowfish denselben Hash mit zwei verschiedenen Salzen?

Lesezeit: 25 Minuten

Warum erzeugt CryptBlowfish denselben Hash mit zwei verschiedenen Salzen
Dereleased

Diese Frage hat mit der PHP-Implementierung von zu tun crypt(). Bei dieser Frage werden die ersten 7 Zeichen des Salzes nicht gezählt, also ein Salz ‘$2a$07$a‘ hätte eine Länge von 1, da es sich nur um 1 Zeichen Salt und sieben Zeichen Metadaten handelt.

Bei Verwendung von Salt-Strings mit mehr als 22 Zeichen ändert sich der generierte Hash nicht (d. h. Kürzung), und bei Verwendung von Strings mit weniger als 21 Zeichen wird das Salt automatisch aufgefüllt (mit ‘$‘ Zeichen, anscheinend); das ist ziemlich einfach. Wenn jedoch einem Salt 20 Zeichen und einem Salt 21 Zeichen gegeben werden, wobei die beiden bis auf das letzte Zeichen des 21-langen Salt identisch sind, sind beide gehashten Zeichenfolgen identisch. Ein 22 Zeichen langes Salt, das bis auf das letzte Zeichen mit dem 21-langen Salt identisch ist, der Hash wird wieder anders sein.

Beispiel im Code:

$foo = 'bar';
$salt_xx = '$2a$07$';
$salt_19 = $salt_xx . 'b1b2ee48991281a439d';
$salt_20 = $salt_19 . 'a';
$salt_21 = $salt_20 . '2';
$salt_22 = $salt_21 . 'b';

var_dump(
    crypt($foo, $salt_19), 
    crypt($foo, $salt_20), 
    crypt($foo, $salt_21), 
    crypt($foo, $salt_22)
);

Wird herstellen:

string(60) "$2a$07$b1b2ee48991281a439d$$.dEUdhUoQXVqUieLTCp0cFVolhFcbuNi"
string(60) "$2a$07$b1b2ee48991281a439da$.UxGYN739wLkV5PGoR1XA4EvNVPjwylG"
string(60) "$2a$07$b1b2ee48991281a439da2.UxGYN739wLkV5PGoR1XA4EvNVPjwylG"
string(60) "$2a$07$b1b2ee48991281a439da2O4AH0.y/AsOuzMpI.f4sBs8E2hQjPUQq"

Warum ist das?

BEARBEITEN:

Einige Benutzer stellen fest, dass es einen Unterschied in der Gesamtzeichenfolge gibt, was wahr ist. In salt_20Offset (28, 4) ist da$.während in salt_21Offset (28, 4) ist da2.; Es ist jedoch wichtig zu beachten, dass die generierte Zeichenfolge den Hash, das Salz sowie Anweisungen zum Generieren des Salzes enthält (dh $2a$07$); der Teil, in dem der Unterschied auftritt, ist tatsächlich immer noch das Salz. Der eigentliche Hash bleibt unverändert UxGYN739wLkV5PGoR1XA4EvNVPjwylG.

Dies ist also kein Unterschied im produzierten Haschisch, sondern ein Unterschied im Salz, das zum Speichern des Haschischs verwendet wird, und genau das ist das Problem: Zwei Salze erzeugen das gleiche Haschisch.

Hinweis: Die Ausgabe erfolgt im folgenden Format:

"$2a$##$saltsaltsaltsaltsaltsaHASHhashHASHhashHASHhashHASHhash"
//                            ^ Hash Starts Here, offset 28,32

wobei ## die log-base-2 ist, die die Anzahl der Iterationen bestimmt, für die der Algorithmus ausgeführt wird

Bearbeiten 2:

In den Kommentaren wurde ich gebeten, einige zusätzliche Informationen zu posten, da der Benutzer meine Ausgabe nicht reproduzieren konnte. Ausführung des folgenden Codes:

var_dump(
    PHP_VERSION, 
    PHP_OS, 
    CRYPT_SALT_LENGTH, 
    CRYPT_STD_DES, 
    CRYPT_EXT_DES, 
    CRYPT_MD5, 
    CRYPT_BLOWFISH
);

Erzeugt die folgende Ausgabe:

string(5) "5.3.0"
string(5) "WINNT"
int(60)
int(1)
int(1)
int(1)
int(1)

Hoffe das hilft.

  • Wenn Sie nur einen kurzen Blick darauf werfen, sehen sie gleich aus, aber es gibt einen Unterschied von 1 Zeichen

    – Craig

    9. Februar 10 um 3:20 Uhr

  • @Craig: Eigentlich ist dieser Teil immer noch das Salz des Hashs, nicht das Hash selbst. Der Hash besteht nur aus den letzten 32 Zeichen.

    – Dereleased

    9. Februar 10 um 22:51 Uhr

  • ahh ok, dann tut mir leid, upvote dafür, dass du mich dumm aussehen lässt 😀

    – Craig

    10. Februar 10 um 0:36 Uhr

Warum erzeugt CryptBlowfish denselben Hash mit zwei verschiedenen Salzen
Dereleased

Nach einigem Experimentieren bin ich zu dem Schluss gekommen, dass dies an der Behandlung des Salzes liegt. Das Salt wird nicht als wörtlicher Text betrachtet, sondern als base64-codierter String, sodass 22 Byte Salt-Daten tatsächlich einen 16-Byte-String darstellen würden (floor(22 * 24 / 32) == 16) aus Salz. Das “Erwischt!” Bei dieser Implementierung wird jedoch, wie bei Unix crypt, ein “nicht standardmäßiges” base64-Alphabet verwendet. Um genau zu sein, verwendet es dieses Alphabet:

./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$

Das 65. Zeichen, ‘$‘, ist das Füllzeichen.

Jetzt die crypt() Die Funktion scheint in der Lage zu sein, ein Salt beliebiger Länge kleiner oder gleich seinem Maximum zu nehmen und alle Inkonsistenzen in base64 stillschweigend zu behandeln, indem alle Daten verworfen werden, die kein weiteres vollständiges Byte ausmachen. Die Crypt-Funktion schlägt vollständig fehl, wenn Sie ihr Zeichen im Salt übergeben, die nicht Teil ihres base64-Alphabets sind, was diese Theorie ihrer Funktionsweise nur bestätigt.

Nimm ein imaginäres Salz ‘1234‘. Dies ist vollkommen base64-konsistent, da es 24 Datenbits darstellt, also 3 Bytes, und keine Daten enthält, die verworfen werden müssen. Dies ist ein Salz, dessen Len Mod 4 ist Null. Fügen Sie diesem Salz ein beliebiges Zeichen hinzu, und es wird ein Salz mit 5 Zeichen, und Len Mod 4 ist jetzt 1. Dieses zusätzliche Zeichen stellt jedoch nur sechs Datenbits dar und kann daher nicht in ein weiteres vollständiges Byte umgewandelt werden, sodass es verworfen wird.

Somit gilt für zwei beliebige Salze A und B, wo

   Len A Mod 4 == 0 
&& Len B Mod 4 == 1  // these two lines mean the same thing
&& Len B = Len A + 1 // but are semantically important separately
&& A == substr B, 0, Len A

Das tatsächliche Salz, das von verwendet wird crypt() um den Hash zu berechnen, wird tatsächlich identisch sein. Als Beweis füge ich einen Beispiel-PHP-Code hinzu, der verwendet werden kann, um dies zu zeigen. Das Salz rotiert ständig in a halbnicht zufällig (basierend auf einem zufälligen Segment des Whirlpool-Hashes der aktuellen Zeit auf die Mikrosekunde genau) und die zu hashenden Daten (hier als $seed) ist einfach die aktuelle Zeit der Unix-Epoche.

$salt = substr(hash('whirlpool',microtime()),rand(0,105),22);
$seed = time();
for ($i = 0, $j = strlen($salt); $i <= $j; ++$i) {
    printf('%02d = %s%s%c',
        $i,
        crypt($seed,'$2a$07$' . substr($salt, 0, $i)),
        $i%4 == 0 || $i % 4 == 1 ? ' <-' : '',
        0x0A
    );
}

Und dies erzeugt eine Ausgabe ähnlich der folgenden

00 = $2a$07$$$$$$$$$$$$$$$$$$$$$$.rBxL4x0LvuUp8rhGfnEKSOevBKB5V2. <-
01 = $2a$07$e$$$$$$$$$$$$$$$$$$$$.rBxL4x0LvuUp8rhGfnEKSOevBKB5V2. <-
02 = $2a$07$e8$$$$$$$$$$$$$$$$$$$.WEimjvvOvQ.lGh/V6HFkts7Rq5rpXZG
03 = $2a$07$e89$$$$$$$$$$$$$$$$$$.Ww5p352lsfQCWarRIWWGGbKa074K4/.
04 = $2a$07$e895$$$$$$$$$$$$$$$$$.ZGSPawtL.pOeNI74nhhnHowYrJBrLuW <-
05 = $2a$07$e8955$$$$$$$$$$$$$$$$.ZGSPawtL.pOeNI74nhhnHowYrJBrLuW <-
06 = $2a$07$e8955b$$$$$$$$$$$$$$$.2UumGVfyc4SgAZBs5P6IKlUYma7sxqa
07 = $2a$07$e8955be$$$$$$$$$$$$$$.gb6deOAckxHP/WIZOGPZ6/P3oUSQkPm
08 = $2a$07$e8955be6$$$$$$$$$$$$$.5gox0YOqQMfF6FBU9weAz5RmcIKZoki <-
09 = $2a$07$e8955be61$$$$$$$$$$$$.5gox0YOqQMfF6FBU9weAz5RmcIKZoki <-
10 = $2a$07$e8955be616$$$$$$$$$$$.hWHhdkS9Z3m7/PMKn1Ko7Qf2S7H4ttK
11 = $2a$07$e8955be6162$$$$$$$$$$.meHPOa25CYG2G8JrbC8dPQuWf9yw0Iy
12 = $2a$07$e8955be61624$$$$$$$$$.vcp/UGtAwLJWvtKTndM7w1/30NuYdYa <-
13 = $2a$07$e8955be616246$$$$$$$$.vcp/UGtAwLJWvtKTndM7w1/30NuYdYa <-
14 = $2a$07$e8955be6162468$$$$$$$.OTzcPMwrtXxx6YHKtaX0mypWvqJK5Ye
15 = $2a$07$e8955be6162468d$$$$$$.pDcOFp68WnHqU8tZJxuf2V0nqUqwc0W
16 = $2a$07$e8955be6162468de$$$$$.YDv5tkOeXkOECJmjl1R8zXVRMlU0rJi <-
17 = $2a$07$e8955be6162468deb$$$$.YDv5tkOeXkOECJmjl1R8zXVRMlU0rJi <-
18 = $2a$07$e8955be6162468deb0$$$.aNZIHogUlCn8H7W3naR50pzEsQgnakq
19 = $2a$07$e8955be6162468deb0d$$.ytfAwRL.czZr/K3hGPmbgJlheoZUyL2
20 = $2a$07$e8955be6162468deb0da$.0xhS8VgxJOn4skeI02VNI6jI6324EPe <-
21 = $2a$07$e8955be6162468deb0da3.0xhS8VgxJOn4skeI02VNI6jI6324EPe <-
22 = $2a$07$e8955be6162468deb0da3ucYVpET7X/5YddEeJxVqqUIxs3COrdym

Das Fazit? Zweifach. Erstens funktioniert es wie vorgesehen, und zweitens kennen Sie Ihr eigenes Salz oder rollen Sie Ihr eigenes Salz nicht.

  • In der Tat. Vielleicht wäre es offensichtlicher gewesen, wenn es ein Standard-Base64-Alphabet verwendet hätte, aber na ja, das Leben geht weiter.

    – Dereleased

    10. Februar 10 um 18:02 Uhr

Warum erzeugt CryptBlowfish denselben Hash mit zwei verschiedenen Salzen
rußnuß

Tolle Antwort und klare Erklärung. Aber es scheint mir, dass entweder ein Fehler in der Implementierung vorliegt oder eine weitere Erklärung der Absicht erforderlich ist {die Kommentare zum Beitrag erklären, warum es keinen Fehler gibt}. Der aktuelle PHP-Dokumentation Zustände:

CRYPT_BLOWFISH – Blowfish-Hashing mit einem Salt wie folgt: „$2a$“, ein zweistelliger Kostenparameter, „$“ und 22 Ziffern zur Basis 64 aus dem Alphabet „./0-9A-Za-z“. Die Verwendung von Zeichen außerhalb dieses Bereichs im Salt führt dazu, dass crypt() eine Zeichenfolge der Länge Null zurückgibt. Der zweistellige Kostenparameter ist der Basis-2-Logarithmus der Iterationszahl für den zugrunde liegenden Blowfish-basierten Hashalgorithmus und muss im Bereich 04–31 liegen, Werte außerhalb dieses Bereichs führen dazu, dass crypt() fehlschlägt.

Dies stimmt mit dem überein, was hier gesagt und demonstriert wurde. Leider beschreibt die Dokumentation den Rückgabewert nicht sehr sinnvoll:

Gibt die gehashte Zeichenfolge oder eine Zeichenfolge zurück, die kürzer als 13 Zeichen ist und sich bei einem Fehler garantiert vom Salt unterscheidet.

Aber wie in der Antwort von Dereleased gezeigt, besteht die Ausgabe, wenn die Eingabe-Salt-Zeichenfolge gültig ist, aus dem Eingabe-Salt, das auf eine feste Länge mit „$“-Zeichen aufgefüllt wird, wobei der 32-stellige berechnete Hash-Wert daran angehängt wird. Leider wird das Salt im Ergebnis auf nur 21 Base64-Ziffern aufgefüllt, nicht auf 22! Dies wird durch die letzten drei Zeilen in dieser Antwort gezeigt, wo wir ein „$“ für 20 Ziffern sehen, kein „$“ für 21, und wenn das Salt 22 Base64-Ziffern enthält, ersetzt das erste Zeichen des Hash-Ergebnisses das 22. Stelle des Eingangssalzes. Die Funktion ist weiterhin verwendbar, da der vollständige Wert, den sie berechnet, dem Aufrufer als zur Verfügung steht substr(crypt($pw,$salt), 28, 32), und der Aufrufer kennt bereits den vollständigen Salzwert, da er diese Zeichenfolge als Argument übergeben hat. Aber es ist sehr schwer zu verstehen, warum der Rückgabewert so ausgelegt ist, dass er Ihnen nur 126 Bit des 128-Bit-Salt-Werts liefern kann. Tatsächlich ist es schwer zu verstehen, warum es überhaupt das Eingangssalz enthält; aber 2 Bits davon wegzulassen ist wirklich unergründlich.

Hier ist ein kleiner Ausschnitt, der zeigt, dass die 22. Base64-Ziffer nur zwei weitere Bits zu dem tatsächlich in der Berechnung verwendeten Salz beiträgt (es werden nur 4 verschiedene Hashes erzeugt):

$alphabet="./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
$lim = strlen($alphabet);
$saltprefix = '$2a$04$123456789012345678901'; // 21 base64 digits


for ($i = 0; $i < $lim; ++$i ) {
  if ($i = 16 || $i == 32 || $i == 48) echo "n";
  $salt = $saltprefix . substr($alphabet, $i, 1);
  $crypt = crypt($password, $salt);
  echo "salt="$salt"ncrypt="$crypt"n";
}

salt="$2a$04$123456789012345678901."
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901/"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901A"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901B"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901C"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901D"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901E"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901F"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901G"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901H"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901I"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901J"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901K"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901L"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901M"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"
salt="$2a$04$123456789012345678901N"
crypt="$2a$04$123456789012345678901.YpaB4l25IJ3b3F3H8trjHXj5SC1UbUW"

salt="$2a$04$123456789012345678901O"
crypt="$2a$04$123456789012345678901Ots44xXtSV0f6zMrHerQ2IANdsJ.2ioG"
salty='$2a$04$123456789012345678901P'
crypt="$2a$04$123456789012345678901Ots44xXtSV0f6zMrHerQ2IANdsJ.2ioG"
salty='$2a$04$123456789012345678901Q'
crypt="$2a$04$123456789012345678901Ots44xXtSV0f6zMrHerQ2IANdsJ.2ioG"
  ... 13 more pairs of output lines with same hash

salt="$2a$04$123456789012345678901e"
crypt="$2a$04$123456789012345678901e.1cixwQ2qnBqwFeEcMfNfXApRK0ktqm"
  ... 15 more pairs of output lines with same hash

salt="$2a$04$123456789012345678901u"
crypt="$2a$04$123456789012345678901u5yLyHIE2JetWU67zG7qvtusQ2KIZhAa"
  ... 15 more pairs of output lines with same hash

Die Gruppierung der identischen Hash-Werte zeigt auch, dass die Zuordnung des tatsächlich verwendeten Alphabets höchstwahrscheinlich so ist, wie hier geschrieben, und nicht in der Reihenfolge, die in der anderen Antwort gezeigt wird.

Vielleicht wurde die Schnittstelle aus Gründen der Kompatibilität auf diese Weise entworfen, und vielleicht kann sie nicht geändert werden, weil sie bereits auf diese Weise ausgeliefert wurde. {Der erste Kommentar zum Beitrag erklärt, warum die Benutzeroberfläche so ist}. Aber sicherlich sollte die Dokumentation erklären, was los ist. Nur für den Fall, dass der Fehler eines Tages behoben wird, wäre es vielleicht am sichersten, den Hash-Wert zu erhalten mit:

substr(crypt($pw,$salt), -32)

Als abschließende Anmerkung noch die Erklärung, warum sich der Hashwert wiederholt, wenn die Anzahl der Base64-Ziffern angegeben ist mod 4 == 1 in Bezug darauf, warum sich Code so verhalten könnte, sinnvoll ist, erklärt es nicht, warum es eine gute Idee war, den Code auf diese Weise zu schreiben. Der Code könnte und sollte wohl die Bits einer Base64-Ziffer enthalten, die bei der Berechnung des Hashs ein Teilbyte ausmacht, anstatt sie einfach zu verwerfen. Wenn der Code so geschrieben worden wäre, wäre das Problem mit dem Verlust der 22. Stelle des Salzes in der Ausgabe wahrscheinlich auch nicht aufgetreten. {Wie die Kommentare zum Beitrag erklären, ist die Ziffer des Hashs, die sie überschreibt, obwohl die 22. Ziffer überschrieben wird, nur einer der vier möglichen Werte [.Oeu], und dies sind die einzigen signifikanten Werte für die 22. Stelle. Wenn die 22. Ziffer keiner dieser vier Werte ist, wird sie durch diejenige dieser vier ersetzt, die denselben Hash erzeugt.}

Angesichts der Kommentare scheint es klar zu sein, dass es keinen Fehler gibt, sondern nur eine unglaublich wortkarge Dokumentation 🙂 Da ich kein Kryptograf bin, kann ich das nicht mit Autorität sagen, aber es scheint mir, dass es eine Schwäche des ist Algorithmus, dass ein 21-stelliges Salt anscheinend alle möglichen Hash-Werte erzeugen kann, während ein 22-stelliges Salt die erste Ziffer des Hashs auf nur einen von vier Werten beschränkt.

  • Ich stimme Ihnen vollkommen zu, den partiellen Bytewert einzubeziehen, den das letzte Zeichen darstellt. Außerdem danke ich Ihnen für dieses interessante Follow-up, im Grunde eine horizontale Erweiterung, die eine andere Eigenart in der gleichen Richtung wie meine vertikale Erweiterung veranschaulicht. Der Grund, warum das Salz an die Zeichenfolge angehängt wird, ist jedoch eigentlich ziemlich einfach: crypt(password, crypt(password, salt)) == crypt(password, salt). Außerdem soll es für bestimmte Mechanismen eine Möglichkeit geben, die automatische Generierung des Salzes auszulösen, also wäre dies der einzige Weg, es zu bekommen. Dein Alphabet stehlen.

    – Dereleased

    4. Januar 11 um 16:23 Uhr

  • Ah, jetzt macht das Format des Rückgabewerts Sinn, danke! Ich wollte gerade sagen, dass es schade ist, dass die Gleichung kaputt ist, wenn Sie tatsächlich ein 22-stelliges Salz verwenden, aber ich sehe, dass das nicht der Fall ist. Während die erste Ziffer des berechneten Hash die 22. Ziffer des eingegebenen Salt überschreibt, passiert Folgendes, wenn die 22. Ziffer eine von ist [.Oeu], diese Ziffer ist auch die erste Ziffer des Hash! Diese base64-Ziffern haben die Werte 0, 16, 32 bzw. 48 – die zwei Bits höherer Ordnung. Die anderen vier Bits werden ignoriert, da das binäre Salt 128 Bits ist und 22 Ziffern 132 Bits wären.

    – rußnuß

    5. Januar 11 um 17:39 Uhr

  • Also wenn die 22. Stelle nicht zählt [.Oeu], der Hash ersetzt ihn durch einen dieser vier, und die Gleichung funktioniert immer noch! Als ich das noch einmal durchgegangen bin, ist mir aufgefallen, dass es in den Daten meines Beitrags Probleme beim Ausschneiden und Einfügen gibt, also werde ich das beheben und auch etwas dazu hinzufügen. Danke noch einmal!

    – rußnuß

    5. Januar 11 um 17:42 Uhr


Sieht so aus, als wären die Ausgänge tatsächlich unterschiedlich. (da$, vs da2) für das Ergebnis von salt_20 und salt_21.

  • Tatsächlich ist dieser Teil immer noch das Salz des Haschischs, nicht das Haschisch selbst. Der Hash besteht nur aus den letzten 32 Zeichen. Ich habe die Frage bearbeitet, um die Tatsache widerzuspiegeln, dass das Salz der Zeichenfolge vorangestellt wird, um die Frage klarer zu machen.

    – Dereleased

    9. Februar 10 um 22:52 Uhr

  • Vielleicht können Sie einige Informationen über Ihre PHP-Version, das Host-Betriebssystem und die Werte der folgenden PHP-Konstanten posten: – CRYPT_SALT_LENGTH – CRYPT_STD_DES – CRYPT_EXT_DES – CRYPT_MD5 – CRYPT_BLOWFISH Wenn ich den von Ihnen geposteten Code ausführe, erhalte ich Folgendes: string(13) "$2yymq4BO0Z3w" string(13) "$2yymq4BO0Z3w" string(13) "$2yymq4BO0Z3w" string(13) "$2yymq4BO0Z3w"

    – H. Grün

    9. Februar 10 um 23:30 Uhr

  • Sie erhalten eine Verschlüsselung mit STD_DES – beachten Sie, dass nur die ersten beiden Zeichen des angegebenen Salzes berücksichtigt werden. Interne Unterstützung für Blowfish (falls nicht von Ihrem Host-Betriebssystem unterstützt) wurde erst mit PHP 5.3 hinzugefügt. Wenn Sie also eine ältere Version haben, wird sie auf die Standardmethode zurückgesetzt, die in Ihrem Setup STD_DES zu sein scheint. Sehen php.net/manual/en/function.crypt.php Für mehr Information.

    – Dereleased

    10. Februar 10 um 0:32 Uhr

  • Ich würde dann wagen, dass die Crypt-Funktion einen internen Mechanismus zum Manipulieren des Salzes hat, sobald es empfangen wird, entweder eine Expansions- oder eine Kontraktionsfunktion, um es auf die richtige Größe für den gegebenen Verschlüsselungsalgorithmus zu bringen (vielleicht behandelt es als base64 und wenn es dekodiert wird). nicht die richtige Anzahl von Bytes zum Lesen enthält, unabhängig von den letzten paar Bytes). Ich habe mir nicht die Zeit genommen, den neuesten PHP-Quellcode zu durchsuchen, um mir das anzusehen, aber wenn Sie wirklich neugierig sind, sollten Sie dort anfangen!

    – H. Grün

    10. Februar 10 um 4:49 Uhr

1643916254 975 Warum erzeugt CryptBlowfish denselben Hash mit zwei verschiedenen Salzen
Walf

Aus meiner Untersuchung ging hervor, dass das Salz immer 22 Zeichen lang ist und der Hash-Offset 29, nicht 28, ist, was eine Länge von 31 Zeichen ergibt, nicht 32. Ich habe diesen Code ausgeführt:

$pass="foobarbazqux";
$salt="cmfh./TCmc3m0X.MnmHGO";
$cost = 8;
$crypt_salt = sprintf('$2a$%02d$%s', $cost, $salt);
$chars="./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for ($i = 0; $i < strlen($chars); $i++) {
    $hash = crypt($pass, $crypt_salt . $chars[$i]);
    var_dump($crypt_salt . $chars[$i], $hash, crypt($pass, $hash));
}

Die Ergebnisse waren:

string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO."
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO/"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO0"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO1"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO2"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO3"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO4"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO5"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO6"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO7"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO8"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGO9"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOA"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOB"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOC"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOD"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOE"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOF"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOH"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOI"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOJ"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOL"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOM"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGON"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGO.t0NzWGmKpRimP4RhjFMg3F020kVKG9S"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOO"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOP"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOQ"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOR"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOS"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOT"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOU"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOV"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOW"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOX"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOY"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOZ"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOa"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOb"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOc"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOd"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOOSYI2wLIE3NElcU7itPPQnj8iW922mwy"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOe"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOf"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOg"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOh"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOi"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOj"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOk"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOl"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOm"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOn"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOo"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOp"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOq"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOr"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOs"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOt"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOeLcyQf2JnDryc7eA43zx3qi1uJKZUtPK"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOu"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOv"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOw"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOx"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOy"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(29) "$2a$08$cmfh./TCmc3m0X.MnmHGOz"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"
string(60) "$2a$08$cmfh./TCmc3m0X.MnmHGOutgqolF/BikhkbIM1yMA7HQpkbDxULoG"

Dies deutet darauf hin, dass der Salt-Teil des zurückgegebenen Hashs nur signifikante Bits speichert, sodass er möglicherweise nicht immer mit Ihrem Eingabe-Salt übereinstimmt. Der Vorteil ist, dass der Hash unverändert als Salz bei der Verifizierung verwendet werden kann. Daher ist es besser, nur den gesamten zurückgegebenen Hash zu speichern crypt(), und niemals das Eingangssalz, das Sie ursprünglich verwenden. In der Praxis:

$hash_to_store = crypt($new_password, $formatted_salt);

und

$verified = $stored_hash == crypt($entered_password, $stored_hash);

Es ist kein Problem, Ihre eigenen Salze zu rollen, und sie zu kennen (ich nehme an, Sie meinten damit, sie getrennt vom Hasch zu lagern) ist nicht erforderlich, wenn Sie sie lagern crypt()‘s Ausgabe wie sie ist.

.

759200cookie-checkWarum erzeugt Crypt/Blowfish denselben Hash mit zwei verschiedenen Salzen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy