2012-12-30 12 views
9

Zajmuję się tworzeniem strony w PHP 5.4 i zastanawiałem się, które z nich lepiej użyć do gen losowej soli dla bezpieczeństwa hasła?czy powinienem używać urandom lub openssl_random_pseudo_bytes?

$salt = sha1(openssl_random_pseudo_bytes(23)); 

lub

$seed = ''; 
$a = @fopen('/dev/urandom','rb'); 
$seed .= @fread($a,23); 
$salt = sha1(seed); 

czy mam po prostu iść z:

$salt = openssl_random_pseudo_bytes(40); 

lub

$salt = ''; 
$a = @fopen('/dev/urandom','rb'); 
$salt .= @fread($a,23); 
+4

Użycie 'sha1()' znacznie zmniejszy skuteczność losowej soli, ponieważ przekształci ją w ciąg znaków składający się z 40 znaków i zawierający tylko znaki 0-9 i -f. Będzie o wiele mniej kombinacji (mniej losowych) niż gdybyś użył 40 bajtów z 'openssl_random_pseudo_bytes()' –

+0

idę z Twoimi sugestiami – John

Odpowiedz

10

Ze względów bezpieczeństwa są lepiej wyłączyć za pomocą openssl_random_pseudo_bytes. OpenSSL zajmuje się gromadzeniem wystarczającej entropii, aby służyć Ci dobrymi przypadkami. /dev/urandom jest opracowywany do nigdy nie ma bloku i można go oszukać, nie dając losowych bajtów.

Z losowymi bajtami nie trzeba ich uruchamiać poprzez SHA1.

Podsumowując to wszystko, zrobić:

$salt = openssl_random_pseudo_bytes(40, $cstrong); 
if (! $cstrong) { 
    exit('This should not happen'); 
} 
+1

Właściwie 'openssl_rand_pseudo_bytes' nie _gwarantuje_ prawdziwej losowości, ani więcej niż '/ dev/urandom' ma; to właśnie oznacza "pseudo" w nazwie. W praktyce jednak oba wyjścia dają wynik niemożliwy do odróżnienia od losowego dowolnym znanym sposobem. –

+0

@IlmariKaronen Oczywiście nie otrzymujesz prawdziwej przypadkowości. Napisałem tylko "dobre"; co OpenSSL nazywa "silną kryptograficznie". Właśnie dlatego testowałem, aby sprawdzić, czy wynik jest silny pod względem kryptograficznym. – kmkaplan

+1

[Nie używaj OpenSSL] (https://github.com/ramsey/uuid/issues/80). –

9

W praktyce jest prawie na pewno nie ma różnicy.

Zarówno openssl_random_pseudo_bytes, jak i /dev/urandom zapewniają bezpieczne kryptograficznie źródło pseudolosowych bajtów. Żadne z nich nie jest gwarantowane, aby być prawdziwie losowo, ale w praktyce oczekuje się, że oba będą nie do odróżnienia od prawdziwej przypadkowości za pomocą jakichkolwiek znanych lub możliwych do przewidzenia technik.

Kmkaplan jest technicznie poprawne zauważyć, że /dev/urandom mógł wrócić wyjście teoretycznie przewidywalne pod pewnymi warunkami, jak zauważono w man unrandom:

„Odczyt z/urandom urządzeniem /dev nie będzie blokować czeka na więcej W rezultacie, jeśli nie ma wystarczającej entropii w puli entropii, zwrócone wartości są teoretycznie podatne na ataki kryptograficzne na algorytmy używane przez sterownik, a wiedza o tym, jak to zrobić, nie jest dostępna w obecnej niesklasyfikowanej literaturze, ale teoretycznie jest możliwe, że taki atak może istnieć, jeśli jest to problemem w twoim aplikowaniu n, zamiast tego użyj /dev/random. "

Jednakże samo rzeczywistości odnosi openssl_random_pseudo_bytes (co calls funkcję OpenSSL RAND_pseudo_bytes wewnętrznie), jak wskazano w OpenSSL documentation:

"RAND_pseudo_bytes() umieszcza num pseudo-losowych bajtów w buf. Pseudo-losowe sekwencje bajtów generowane przez RAND_pseudo_bytes() będą niepowtarzalne, jeśli mają wystarczającą długość, ale niekoniecznie są nieprzewidywalne. Mogą być używane do celów niekryptograficznych i do niektórych celów w wołaniu protokoły ptograficzne, ale zwykle nie do generowania kluczy itp."

Żadne z tych ostrzeżeń powinien faktycznie straszyć z użyciem tych metod — one opisują są tylko teoretyczne, z wyjątkiem być może w pewnych okolicznościach contrived (takich jak na bezdyskowych urządzenia wbudowanego bez RNG sprzętu natychmiast po rozruchowym słabości w górę) i nie powinno stanowić problemu praktycznego w sytuacjach, gdy PHP jest normalnie wdrażane.

W żadnej z tych metod generowania liczb losowych nie ma być the weakest link w twoim kryptosystemie, więc możesz bezpiecznie wybrać jedną z nich. Jeśli czujesz się paranoidalnie, możesz użyć obu.


Ps. Jedną z zalet openssl_random_pseudo_bytes jest to, że działa również w systemie Windows. Z drugiej strony, /dev/urandom jest dostępny w systemie Unix, nawet jeśli rozszerzenie PHP OpenSSL nie jest zainstalowane. W związku z tym, aby uzyskać maksymalną przenośność, należy faktycznie wdrożyć obsługę obu.

Sprawdź też, czy rzeczywiście otrzymałeś tyle bajtów, ile się spodziewałeś; na przykład kod oparty na powyższym pytaniu może w trybie milczącym zwrócić pusty ciąg znaków w systemach takich, jak Windows, gdzie nie istnieje /dev/urandom.

+0

'RAND_pseudo_bytes' i' openssl_random_pseudo_bytes' zwraca kod, który mówi "jeśli wygenerowane bajty są silne pod względem kryptograficznym". – kmkaplan

Powiązane problemy