2016-02-26 28 views
1

因爲我使用的是較老版本的PHP,所以我必須使用.crypt()。我正在測試一些密碼驗證,並且服務器驗證錯誤的密碼是正確的。於是我決定去最基本的測試可能,我還是有這個問題:對於不同的字符串和鹽,PHP .crypt()的結果是一樣的

<?php 
echo crypt("cryptcryptcrypt","salt"); 
echo "<br>"; 
echo crypt("cryptcryptcrypta","salta"); 
?> 

- 其結果是:

saRyxun8Pn/K6 
saRyxun8Pn/K6 

這是爲什麼hapening?


出於測試目的,我使用PhpFiddle,所以回答時,你可能會發現這很有用...

+0

'它也只使用str的前8個字符,所以以相同的8個字符開始的更長的字符串將會生成相同的結果(當使用相同的鹽時).'解釋了部分問題。爲什麼他們爲兩種不同的鹽產生相同的輸出,完全是另一個問題。 @Sberry, – sberry

+0

,鹽應該不一樣嗎? –

+0

@ 1615903,可悲的是,我沒有5.3.7。 –

回答

8

引述docs

標準的基於DES-的crypt()返回鹽作爲輸出的前兩個字符。它也只使用str的前八個字符,所以以相同的八個字符開頭的較長的字符串將生成相同的結果(當使用相同的鹽時)。

您提供的鹽只有4或5個字符長,這使得crypt使用標準的基於DES的算法。所以,只使用前9個字符的密碼,並且只使用前兩個字符的鹽。因此你的哈希值是相等的。你真的應該更新你的PHP版本,所以你可以使用現代的password_hash函數。如果這不可行,請嘗試使用與PHP 3和更高版本兼容的http://www.openwall.com/phpass/。如果這是不可能的,請閱讀...

您需要將正確格式的salt傳遞給crypt函數。從文檔中的示例:

if (CRYPT_BLOWFISH == 1) { 
    echo 'Blowfish:  ' . crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$') . "\n"; 
} 

if (CRYPT_SHA256 == 1) { 
    echo 'SHA-256:  ' . crypt('rasmuslerdorf', '$5$rounds=5000$usesomesillystringforsalt$') . "\n"; 
} 

if (CRYPT_SHA512 == 1) { 
    echo 'SHA-512:  ' . crypt('rasmuslerdorf', '$6$rounds=5000$usesomesillystringforsalt$') . "\n"; 
} 

散列的開頭定義了要使用的算法。您還需要確保您爲每個用戶使用隨機獨特的鹽。

+0

你的問題是「爲什麼發生這種情況」,所以我回答說 - 我現在修改了我的答案,包括改善情況的建議。 – 1615903

+0

是的!那很好 :)。但這是否也很好? '$ password = crypt($ password,'$ 6 $ rounds = 5000'。$ salt。'$');' –

+2

這需要支持需要PHP 5.3.2的SHA-512,我的印象是你正在使用舊版本。你有哪個PHP版本? – 1615903

相關問題