2015-05-25 33 views
2

使用密碼「TESTTEST」和哈希「KFtIFW1vulG5nUH3a0Mv」與在依賴於PHP版本不同的散列以下代碼結果的兩個不同的值(如下面的圖像中):crypt函數輸出取決於PHP版本

$salt = "KFtIFW1vulG5nUH3a0Mv"; 
$password = "testtest"; 

$key = '$2a$07$'; 
$key = $key.$salt."$"; 

echo crypt($password, $key); 

輸出1(PHP v.5.3.0 - 5.4.41,21年5月5日 - 5.5.25,5.6.5 - 5.6.9):$2a$07$KFtIFW1vulG5nUH3a0Mv$.0imhrNa/laTsN0Ioj5m357/a8AxxF2q

輸出2(PHP v.5.5.0 - 5.5.20,5.6.0-5.6.4):$2a$07$KFtIFW1vulG5nUH3a0Mv$e0imhrNa/laTsN0Ioj5m357/a8AxxF2q

這是一個問題的例子m: http://3v4l.org/dikci

這是一個大問題,如果crypt被用於哈希登錄密碼,依賴於PHP版本哈希會有所不同。任何人都明白這個問題是從哪裏來的,以及如何處理它?

enter image description here

+0

define *「取決於PHP版本」*並閱讀手冊http://php.net/crypt –

+0

看看附件中的圖片,某些PHP版本輸出的結果與其他版本不同。我現在將添加細節。 – JimmyBanks

+0

我在高分辨率;很難看到它;需要眯眯 –

回答

2

這與其說是因爲你可能會想到一個問題。

首先您應該注意,您的代碼不是絕對正確的,BCrypt需要22個字符的鹽,但是您提供了20個字符的鹽。這意味着終止'$'(這是不必要的btw)將被視爲鹽的一部分,以及您的密碼的第一個字母。雖然$不是BCrypt鹽的有效字符。

要考慮的另一件事是,並非所有字符22的位都被使用,這是由於編碼,ircmaxell給出了關於這個good explanation。所以不同的鹽可以產生相同的散列,你可以在這個answer中看到。不同的實現如何處理角色22的這最後一個比特在理論上可以改變。只要crypt函數可以用兩個哈希驗證密碼,就沒有問題。

鹽的產生與其陷阱是其中的原因之一,爲什麼函數password_hash()password_verify()在哪裏寫,他們使密碼處理更容易。

+0

你完全正確,將salt改爲22個字符會得到一致的輸出結果。 – JimmyBanks

+0

這裏的例子http://php.net/crypt有'$'拖鹽,這是爲什麼? – JimmyBanks

+1

@JimmyBanks - 這些例子確實有點誤導,評論說:「這些鹽只是例子,不應該在你的代碼中逐字使用。你應該爲每個密碼生成一個明確的,正確格式的鹽。此外,他們使用現在應該用'2y'代替的算法'2a'。似乎他們忘記了更新文檔,可能是因爲無論如何應該使用'password_hash()'函數。 – martinstoeckli