2012-12-19 110 views
0

可能重複:
How do you use bcrypt for hashing passwords in PHP?存儲密碼進行用戶登錄

我研究加密和存儲在登錄數據庫的用戶密碼的最佳和最安全的方法。我碰到的一篇文章,Salted Password Hashing - Doing it Right,提供了一個相當複雜的功能,用於加密和檢查密碼。

我明白代碼是如何工作的,但文章中還提到不僅在數據庫中存儲哈希密碼,而且還在鹽中存儲哈希密碼。如何使用給定的代碼去做這件事?例如:

// User registers with username and password; assume they're already validataed 
$hash = create_hash($password_entered); 
$password_hash = $hash[HASH_PBKDF2_INDEX]; 
$salt = $hash[HASH_SALT_INDEX]; 

$PDO = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password); 
$statement = $PDO->prepare('INSERT INTO users (username, password, user_salt) 
    VALUES (:username, :password; :user_salt)'); 
$statement->execute(array(
    ':username' => $username_entered, 
    ':password' => $password_hash, 
    ':user_salt' => $salt, 
)); 

這似乎是正確的。但是,驗證登錄的時候,我不知道檢查什麼對從登錄表單輸入的密碼。由create_hash()返回的編譯散列給出了冒號分隔的值列表。我只是不確定該從哪裏下載,或者如果這個源代碼甚至值得使用。

+3

如果你正在尋找最安全的方式。不要自己動手。要麼等到原生密碼API爲PHP 5.5,要麼同時使用[compat lib](https://github.com/ircmaxell/password_compat)。 – PeeHaa

+2

你是不是應該使用文章中的'validate_password'函數?正如你寫的,'create_hash'返回一個字符串,它已經包含了重新創建它所需的一切(算法,迭代,哈希和鹽),所以你只需要存儲該連接字符串。 – Groo

+2

看起來像'create_hash'函數將salt與hash一起嵌入(一種常見做法),因此不需要將salt單獨存儲在用戶記錄中。 –

回答

1

我還沒有使用這段代碼,但我敢肯定你不應該將user_salt單獨保存在用戶表的一列中。用戶salt將包含在散列中(位於冒號分隔的散列中的位置3)。在您的登錄腳本,得到密碼的用戶已經進入,並調用以下功能:

// here run a query and get the hashed password from the users table and put the 
// hashed value in $hashed_password_from_database 
// $user_enetered_password usually comes from $_POST 

if (validate_password($user_entered_password, $hashed_password_from_database)) { 
    // login successful 
} else { 
    // login failed 
} 
+0

哦,我明白了!當它提到將salt存儲在數據庫中時,它意味着'create_hash()'生成的整個逗號分隔值。我現在明白了。謝謝! – TerranRich

1

爲了驗證登錄,使用下面的函數,你發佈的鏈接上發現,隨着$password而密碼由輸入用戶試圖登錄,並$good_hashPBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" . $salt_from_db . ":" . $hash_from_db

function validate_password($password, $good_hash) 
{ 
    $params = explode(":", $good_hash); 
    if(count($params) < HASH_SECTIONS) 
     return false; 
    $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]); 
    return slow_equals(
     $pbkdf2, 
     pbkdf2(
      $params[HASH_ALGORITHM_INDEX], 
      $password, 
      $params[HASH_SALT_INDEX], 
      (int)$params[HASH_ITERATION_INDEX], 
      strlen($pbkdf2), 
      true 
     ) 
    ); 
}