2013-03-05 14 views
9

Uczę się o funkcji crypt() PHP i przeprowadziłem z nią kilka testów. Według this post, powinienem użyć soli o długości 22 znaków. Mogę jednak użyć ciągu znaków o długości 23 znaków z pewnymi ograniczeniami. Kiedy używam 22-znakowego łańcucha, zawsze otrzymuję wynik "$ 2y $ xxStringStringStringStri.HashHashHashHashHashHashHashHas". Wiem, że okres jest po prostu częścią soli.Dlaczego nie powinienem używać 23. znaku w soli funkcji krypta()?

Wygląda na to, że jeśli użyję 23 znaków zamiast tylko 22, uda mi się wygenerować różne skróty, ale tylko 4 różne wyniki dla wszystkich 64 znaków. 23. Znak „zaokrągla w dół” z dokładnością do 1/4 z alfabetu 64 znaków (na przykład 23. postać jest „W” i zaokrągla w dół „O” lub dowolną liczbę rund do litery „U”)

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

Wszystkie cztery z tych funkcji krypt wytworzenia tej samej soli:

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

Ale to jest inna:

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

Więc dlaczego nie powinno się używać 23 charakter, kiedy z powodzeniem może wygenerować różne wyniki? Czy jest jakiś rodzaj niestabilnego zachowania w PHP, którego należy unikać, nie używając go?

Dla wyjaśnienia, w jaki sposób liczę 23 znaków w soli:

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

Istnieje dobre wyjaśnienie na to pytanie: http://security.stackexchange.com/questions/20862/php-crypt-trims-the-salt-as-it-would-be-too-long –

+0

Dziękuję za ta odpowiedź. Chociaż dotyczy to tylko tego, co dzieje się z 23. znakiem, ponieważ jest ono skracane tylko z powodu rozmiaru bitów dozwolonych w funkcji crypt(). Moje pytanie, w inny sposób pytające, brzmi: "Czy powinienem używać 23 litery, nawet jeśli zostanie porąbane na dwa kawałki?" lub w inny sposób: "Czy jest jakiś błąd w algorytmie PHP, który generuje niepoprawne hashy, gdy używany jest 23 znak?" – Andrew

Odpowiedz

2

Ma do czynienia z kolizjami hash. Po przekroczeniu 22 znaków wygenerowane hasze nie są już unikalne w zależności od algorytmu NAMESPACE. Mówiąc inaczej, ponad 22 znaki nie powodują zwiększenia bezpieczeństwa i mogą obniżyć poziom bezpieczeństwa.

+1

Wydaje mi się, że dodaje 2 dodatkowe elementy bezpieczeństwa. Nadal mogę generować różne hashe, zmieniając inne postacie w soli, pozostawiając 23-te, powiedzmy "a". Czy istnieje artykuł o przelaniu soli? Nawet na [php.net] (http://php.net/manual/en/function.crypt.php) używają przykładu soli o ponad 22 znakach. – Andrew

+1

Oczywiście wygeneruje on różne wyniki, ale jeśli użyjesz 23 znaków, pojawi się kolejny ciąg znaków, który spowoduje dokładnie ten sam skrót. To się nazywa kolizja i nie chcesz tego, gdy starasz się, aby wszystko było unikalne. –

+0

Hmmm .... Nie jestem pewien jak to wyjaśnić, ale mogę zagwarantować, że używanie 23 znaków w soli (nawet jeśli zdarzają się kolizje solne, jak powiedziałeś) jest bezpieczniejsze niż użycie 22. Wyjaśnienie: Powiedzmy mamy mniejszą formę blowfish. W tym mini bowfish możemy umieścić sól o długości 1 znak, na przykład "a" lub "4" lub "I".Istnieje 64 różne kombinacje, które możemy wykonać, zanim zaczniemy się zderzenia z solą. Możemy jednak dodać tylko 2 dodatkowe bity (".", "O", "e" i "u") i zamienić kombinację 64 unikatowych soli w 256. Nawet, jeśli nie pełny alfabet, jest bezpieczniejszy. – Andrew

0

$ nie jest częścią rzeczywistej soli. To jest separator.

Dla krypty Blowfish format to 2 $ [axy] $ log2Rounds $ [salt] [hash]. Opisujesz to dodając. - to dlatego, że brakuje ci ostatniej postaci. Sól Blowfish jest 128 bitów. Możesz użyć tylko 126, tak, ale po prostu niepotrzebnie osłabiasz sól.

+0

Jeśli używasz zbyt wielu znaków, przy okazji, absolutnie dobrze z crypt(), ponieważ jest przeznaczony do użycia jako krypta (hasło, sól) do krypty, cryptedPassword == krypta (hasło, szyfrowane hasło) do weryfikacji, i robi to przez dołączenie skrótu do soli na wyjściu i tylko używając odpowiednich bajtów soli na wejściu. Więc widzisz, dodatkowe postacie po prostu nie będą używane. – Zer

Powiązane problemy