2014-02-13 67 views
0

我試圖匹配來自數據庫的哈希密碼與密碼 - 散列從登錄表單,它不匹配,不管什麼。Laravel 4.1哈希::使不一致

然後我做了一些一致性測試。

$password = Hash::make('secret'); 
echo $password; 

我每次刷新頁面時都會得到不同的結果。不像md5,它是一致的。

我錯過了什麼嗎?

或者我使用/做錯了嗎?

爲什麼Hash :: make會產生具有相同參數的不一致結果?

回答

2

這是正確的,這是設計。

據我所知,該函數使用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; 
} 
+0

嗯。偉大的信息。那麼,我怎樣才能比較SQL級別的散列密碼?我看到的唯一解決方案是獲取密碼(查詢),然後使用Hash :: check ...獲取密碼,必須找到與用戶名匹配的記錄。但我想在我的查詢上進行兩列搜索/匹配。 – Craftein

+1

我不認爲你可以在數據庫級別這樣做,或者它會非常黑客和困難 - 通常它是在處理級別完成的,我沒有理由避免這種情況 –

0
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);