2012-12-30 297 views
9

我正在PHP 5.4中開發一個站點,我想知道哪個更好用來創建密碼安全的隨機鹽?我應該使用urandom還是openssl_random_pseudo_bytes?

$salt = sha1(openssl_random_pseudo_bytes(23)); 

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

,或者我應該只是去:

$salt = openssl_random_pseudo_bytes(40); 

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

使用'SHA1()'將大大降低你的隨機鹽的有效性,因爲這將其轉換成字符串,它是40個字符,並僅含有0-9和A-F的字符。會有少了很多組合(意爲隨機的),比如果你只是使用40個字節'openssl_random_pseudo_bytes()' –

+0

我與您的兩個建議去 – John

回答

10

爲了安全起見,你最好使用openssl_random_pseudo_bytes。 OpenSSL負責收集足夠的熵來爲您提供良好的隨機性。 /dev/urandom被設計爲從來沒有塊,並可能欺騙,讓你沒有這麼隨機的字節。

隨機字節您不需要通過SHA1運行它們。

總之這一切,做到:

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

事實上,'openssl_rand_pseudo_bytes'沒有任何_guarantee_真正的隨機性,任何更多比'/ dev/urandom'確實;這就是名字中的'pseudo'意思。然而,在實踐中,兩者都通過任何已知的手段產生無法區分的和隨機的。 –

+0

@IlmariKaronen當然,你不會得到真正的隨機性。我只寫了「好」; OpenSSL稱之爲「密碼強大」。這就是爲什麼我在測試中檢查結果是否具有密碼強度。 – kmkaplan

+1

[不要使用OpenSSL](https://github.com/ramsey/uuid/issues/80)。 –

9

在實踐中,幾乎可以肯定是沒有什麼區別。

openssl_random_pseudo_bytes/dev/urandom都提供了密碼安全的僞隨機字節源。它們都不是隨機的,但實際上,它們都可以通過任何已知或可預見的技術與真正的隨機性區分開來。

Kmkaplan是在指出的是/dev/urandom可以在一定條件下返回理論上預測的輸出,如在man unrandom指出技術上正確:

「從的/ dev/urandom的裝置的讀不會阻塞等待更多因此,如果熵池中沒有足夠的熵,則返回的值在理論上容易受到對駕駛員所用算法的加密攻擊,在當前未分類的文獻中不知道如何做到這一點,但理論上可能存在這樣的攻擊,如果這是你應用中的一個問題n,改爲使用/dev/random。「

然而,同樣是openssl_random_pseudo_bytes(其calls OpenSSL的功能RAND_pseudo_bytes內部)實際上的確,正如在OpenSSL documentation注意到:

RAND_pseudo_bytes()提出NUM僞隨機字節到BUF。由RAND_pseudo_bytes()生成的僞隨機字節序列如果長度足夠,但不一定是不可預知的,則它們將是唯一的。它們可以用於非加密目的以及用於某些目的ptographic協議,但通常不用於密鑰生成等。「

無論這些警告實際上應該嚇唬你使用這些方法—他們描述僅僅是理論上的,除了可能在某些人爲的情況下(如與boot-後沒有硬件RNG無盤嵌入式設備上的弱點以上),不應在以下情況下的實際關注,其中PHP通常部署的。

的結果是,沒有這些隨機數產生方法將是在您的密碼the weakest link,所以你可以放心地選擇任何一個。如果你感到偏執,你甚至可以同時使用。


詩篇。 openssl_random_pseudo_bytes的一個優點是它也可以在Windows上運行。另一方面,即使沒有安裝OpenSSL PHP擴展,在Unix上也可以使用/dev/urandom。因此,爲了獲得最大的可移植性,你應該確實實現對兩者的支持。

此外,經常檢查你預計你確實收到許多字節;例如,上述問題中基於/dev/urandom的代碼可能會在不存在/dev/urandom的Windows系統上以無提示方式返回空字符串。

+0

'RAND_pseudo_bytes'和'openssl_random_pseudo_bytes'返回一個代碼,告訴你「如果生成的字節是密碼強的」。 – kmkaplan

相關問題