2012-12-19 111 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 
     ) 
    ); 
}