2013-03-05 11 views
9

Ich lerne über PHP crypt() -Funktion und habe einige Tests mit ihm ausgeführt. Nach this post sollte ich ein Salz verwenden, das 22 Zeichen lang ist. Ich kann jedoch eine Zeichenfolge verwenden, die 23 Zeichen lang ist, mit einigen Einschränkungen. Wenn ich eine 22 Zeichen lange Zeichenfolge verwende, bekomme ich immer ein Ergebnis von '$ 2y $ xxStringStringStriStri.HashHashHashHashHashHashHashHas'. Ich weiß, dass die Zeit nur ein Teil des Salzes ist.Warum sollte ich nicht das 23. Zeichen in einer crypt() - Funktion verwenden?

Es scheint, dass wenn ich 23 statt 22 Zeichen verwende, kann ich erfolgreich verschiedene Hashes generieren, aber es gibt nur 4 verschiedene Ergebnisse für alle 64 Zeichen. Die 23. Zeichen „rundet“ auf die nächste 1/4 der 64 Zeichenalphabet (zum Beispiel die 23. Zeichen „W“ und rundet auf „O“ oder eine beliebige Zahl abrundet zu „u“)

v---------------v---------------v---------------v--------------- 
./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 

Alle vier dieser Krypta Funktionen erzeugen die gleiche Salz:

crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAq'); 
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAr'); 
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAs'); 
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAt'); 

Aber das ist anders:

crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAu'); 

warum sollte ich also nicht das 23. Zeichen verwenden, wenn es erfolgreich unterschiedliche Ergebnisse erzeugen können? Gibt es in PHP ein Glitchy-Verhalten, das vermieden werden sollte, indem man es nicht benutzt?

Zur Klarstellung auf, wie ich den 23. Charakter in dem Salz zählen:

crypt('Test123','$2y$08$ABCDEFGHIJKLMNOPQRSTUV'); 
//  The salt is '$ABCDEFGHIJKLMNOPQRSTUV' 
//  Which will be treated as '$ABCDEFGHIJKLMNOPQRSTUO' 
+1

Es gibt eine gute Erklärung zu dieser Frage: http://security.stackexchange.com/questions/20862/php-crypt-trims-the-salt-as-it-would-be-too-long –

+0

Vielen Dank für diese Antwort. Obwohl dies nur anspricht, was mit dem 23. Zeichen passiert, wird es nur aufgrund der Größe der Bits, die in der Funktion crypt() erlaubt sind, verkürzt. Meine Frage, auf eine andere Art und Weise zu fragen, ist "Soll ich das 23. Zeichen verwenden, auch wenn es in zwei Bits zerstückelt wird?" oder ein anderer Weg ist "Gibt es einen Fehler im PHP-Algorithmus, der falsche Hashes generiert, wenn das 23. Zeichen verwendet wird?" – Andrew

Antwort

2

Es hat mit Hash-Kollisionen zu tun. Sobald Sie 22 Zeichen überschreiten, sind die generierten Hashes nicht mehr abhängig von NAMESPACE des Algorithmus. Um es anders auszudrücken, mehr als 22 Zeichen führen zu keiner erhöhten Sicherheit und können Ihr Sicherheitsniveau sogar verringern.

+1

Es scheint mir, als ob es 2 weitere Bits Sicherheit hinzufügt. Ich kann immer noch verschiedene Hashes erzeugen, indem ich andere Charaktere im ganzen Salz ändere, während ich den 23. als "a" belasse. Gibt es einen Artikel über das Überlaufen des Salzes? Sie verwenden sogar auf [php.net] (http://php.net/manual/en/function.crypt.php) ein Beispiel für ein Salz mit mehr als 22 Zeichen. – Andrew

+1

Natürlich wird es andere Ergebnisse generieren, aber wenn Sie 23 Zeichen verwenden, gibt es eine andere Zeichenfolge, die genau den gleichen Hash ergibt. Dies nennt man eine Kollision und das wollen Sie nicht, wenn Sie versuchen, alles einzigartig zu halten. –

+0

Hmmm .... Ich bin nicht sicher, wie ich das erklären soll, aber ich kann Ihnen garantieren, dass die Verwendung von 23 Zeichen in einem Salz (obwohl es Salzkollisionen gibt, wie Sie sagten) sicherer ist als die Verwendung von 22. Erläuterung: Sagen wir Wir haben eine kleinere Form von Kugelfisch. In diesem Mini-Bowfish können wir ein Salz mit einer Länge von 1 Zeichen wie "a" oder "4" oder "I" eingeben.Es gibt 64 verschiedene Kombinationen, die wir damit machen können, bevor wir Salzkollisionen bekommen. Wir können jedoch nur zwei weitere Bits (".", "O", "e" und "u") hinzufügen und eine Kombination von 64 einzigartigen Salzen in 256 umwandeln. Selbst wenn nicht das volle Alphabet, ist es sicherer. – Andrew

0

$ ist nicht Teil des eigentlichen Salzes. Es ist ein Separator.

Für Blowfish Krypta ist das Format $ 2 [axy] $ log2Rounds $ [Salz] [Hash]. Du beschreibst es mit einem. - weil du das letzte Zeichen verpasst hast. Blowfishs Salz ist 128 Bits. Sie könnten nur 126 verwenden, ja, aber Sie sind nur unnötig das Salz zu schwächen.

+0

Wenn Sie tatsächlich zu viele Zeichen verwenden, sind Sie mit crypt() absolut in Ordnung, da es als Krypta (Passwort, Salz) für crypt, cryptedPassword == crypt (Passwort, cryptedPassword) zur Verifizierung verwendet werden soll. und zwar durch Anhängen des Hash an das Salz bei der Ausgabe und nur unter Verwendung der relevanten Salzbyte bei der Eingabe. Du wirst sehen, dass zusätzliche Zeichen nicht verwendet werden. – Zer