我試圖匹配來自數據庫的哈希密碼與密碼 - 散列從登錄表單,它不匹配,不管什麼。Laravel 4.1哈希::使不一致
然後我做了一些一致性測試。
$password = Hash::make('secret');
echo $password;
我每次刷新頁面時都會得到不同的結果。不像md5,它是一致的。
我錯過了什麼嗎?
或者我使用/做錯了嗎?
爲什麼Hash :: make會產生具有相同參數的不一致結果?
我試圖匹配來自數據庫的哈希密碼與密碼 - 散列從登錄表單,它不匹配,不管什麼。Laravel 4.1哈希::使不一致
然後我做了一些一致性測試。
$password = Hash::make('secret');
echo $password;
我每次刷新頁面時都會得到不同的結果。不像md5,它是一致的。
我錯過了什麼嗎?
或者我使用/做錯了嗎?
爲什麼Hash :: make會產生具有相同參數的不一致結果?
這是正確的,這是設計。
據我所知,該函數使用password_hash() PHP函數,並且默認爲PASSWORD_BCRYPT標誌,
PASSWORD_BCRYPT - 使用算法crypt_blowfish的創建 哈希值。這將使用 「$ 2y $」標識符產生標準crypt()兼容散列。結果將始終爲60個字符的字符串,或者 失敗時爲FALSE。
這意味着鹽在每個呼叫自動產生的,和內插入生成的字符串,它包含:用於ALGO的標識符(在這種情況下,$2y$
),則迭代成本(默認爲12) ,哈希密碼和生成的隨機鹽。
這意味着,因此,每次你散列你的密碼一個新的鹽被創建,因此字符串將永遠是不同的 - 即使密碼是相同的。這是一個一個的優勢,而不是使用簡單的md5散列。要檢查它,你需要使用Hash :: check()函數,它使用password_verify()php函數來分析哈希值,猜測使用的算法,使用嵌入的鹽值,因此可以檢查過程,給定相同的開始條件,創建一個相同的散列。
編輯
事實上,這是該方法(在Illuminate/Hashing/BcryptHasher
)
* Hash the given value.
*
* @param string $value
* @param array $options
* @return string
*/
public function make($value, array $options = array())
{
$cost = isset($options['rounds']) ? $options['rounds'] : $this->rounds;
$hash = password_hash($value, PASSWORD_BCRYPT, array('cost' => $cost));
if ($hash === false)
{
throw new \RuntimeException("Bcrypt hashing not supported.");
}
return $hash;
}
Validator::extend('old_password', function($attribute, $value, $parameters) {
return Hash::check($value, Auth::user()->password);
});
$rules = array(
'old_password' => 'required|old_password',
'new_password' => 'required|confirmed'
);
$messages = array(
'old_password' => 'wrong old password'
);
$validator = Validator::make($data = $input, $rules, $messages);
嗯。偉大的信息。那麼,我怎樣才能比較SQL級別的散列密碼?我看到的唯一解決方案是獲取密碼(查詢),然後使用Hash :: check ...獲取密碼,必須找到與用戶名匹配的記錄。但我想在我的查詢上進行兩列搜索/匹配。 – Craftein
我不認爲你可以在數據庫級別這樣做,或者它會非常黑客和困難 - 通常它是在處理級別完成的,我沒有理由避免這種情況 –