我即將使用這個用戶密碼系統,但我首先要確保我做得正確。這裏是我的測試代碼:我在PHP中正確使用CRYPT_BLOWFISH嗎?
function generateBlowfishSalt() { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./'; $numChars = strlen($chars); $salt = ''; for($i = 0; $i < 22; ++$i) { $salt .= $chars[mt_rand(0, $numChars - 1)]; } return $salt; } $password = 'foo'; $salt = generateBlowfishSalt(); $hash1 = crypt($password, '$2a$12$' . $salt); $hash2 = crypt($password, $hash1); $compare = ($hash1 == $hash2); printf('password: %s</br>', $password); printf('salt: %s</br>', $salt); printf('hash1: %s</br>', $hash1); printf('hash2: %s</br>', $hash2); printf('compare: ' . $compare);
下面是一個示例輸出:
password: foo salt: MYVJ32OqLcMGBar3pUa.0S hash1: $2a$12$MYVJ32OqLcMGBar3pUa.0OTRwv6UX0bcxnSmheKOcqjvqvCrM/p2q hash2: $2a$12$MYVJ32OqLcMGBar3pUa.0OTRwv6UX0bcxnSmheKOcqjvqvCrM/p2q compare: 1
我的主要問題是:
我是否正確產生了22字符鹽?我見過的一些實現使用
base64_encode()
來生成鹽。我需要這樣做嗎?將數據庫中的整個
$hash1
值存儲起來並且不存儲單獨的鹽值是否正確,因爲$hash1
將有鹽分,這就是我需要驗證密碼的全部內容嗎?在PHP
crypt()
文檔頁面的CRYPT_BLOWFISH
例子有對鹽論證後$
(那就是:'$2a$07$usesomesillystringforsalt$'
)。但在所有的例子中,我看到沒有人使用尾隨$
。它是可選的嗎?
感謝
鹽不是隨機的嗎?我使用mt_rand()來生成它。我認爲我不需要在crypt()返回的值的頂部存儲單獨的salt值,因爲crypt()返回的值幾乎包含了整個鹽值。此外,我只需要第一次調用crypt()以返回值以驗證密碼。 – Ryan
是的,你不需要做任何額外的事情。你正在生成隨機鹽。我很確定我說過「你在正確地做鹽」。只是重申它。你有正確的想法。 – Andy