PHP 5.5散列API和散列纯文本密码已存在于数据库中

时间:2014-11-04 14:12:42

标签: php mysql sql hash passwords

我找到了下面引用的问题的解决方案,可以帮助人们使用PHP PDO。我测试了它并且它可以工作,但我不确定它是最干净的代码还是最好的代码。欢迎任何改进。

以下是供参考的原始问题:

我想哈希已存在于MySQL数据库中的密码。我已经可以使用php 5.5散列API散列新密码,但我想知道是否有办法获取所有旧的纯文本密码并将它们转换为bcrypt哈希。我现在想的是将密码复制到一个名为'hash'的新行,并在检查它们是否正确复制后,将它们转换为哈希值。我不知道如何复制密码行并在同一个表上重命名,或者如何最有效地散列所有这些。

任何见解都将受到赞赏。

以下是解决方案:

    <?
    // IMPORTANT: only call this script one time or you will double hash and the passwords input by your users won't work anymore

    // Get Configuration file
    require("configsecuresavedgames.php");

    // Connect to your server

    $dbh = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8" , $user, $pass);  
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);


    ///////////////////////////////////////////////////////
    // Upload new score
    ///////////////////////////////////////////////////////

// set variable $x to 1 to start at ID 1 and then update each row in a loop, adding 1 to the $x variable once done 

$x = 1; 
// Note: Change the statement below so that the number is larger to match the number of users in your database

while($x <= 100) {

// select hash for each row...
  $stmt = $dbh->prepare("SELECT hash FROM $tname WHERE id = $x"); 
    $stmt->execute();

    // set the resulting array to associative
    $result = $stmt->setFetchMode(PDO::FETCH_ASSOC); 

// set $hash variable to hash (from database) for the respective row

    while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo $row['hash'];
    $hash = $row ['hash'];
}

// update hash row with new hash data (note: prior to running the script make sure that you've copied all plain text passwords to the hash row in the database.


    $newhash = password_hash($hash, PASSWORD_DEFAULT);
    $sql = "UPDATE securesavegames SET hash = '$newhash' WHERE id = $x";


     // Prepare statement
    $stm = $dbh->prepare($sql);

    // execute the query
    $stm->execute();

    // echo a message to say the UPDATE succeeded
    echo $stm->rowCount() . " records UPDATED successfully";

    // add to $x so that the hash for the next 'id' will be updated, then the loop will continue.

 $x++;

}  
$dbh = null;

?>

1 个答案:

答案 0 :(得分:1)

如果您的密码是纯文本的,只需将它们传递给哈希就可以了。

使用一个查询进行更新并不是一种简单的方法,因为password_hash是一个PHP函数。您必须获取值然后循环它们。准备好的陈述对此有很大的帮助。

 $sql = 'SELECT record_id, password FROM table';
 $res = $mysqli->query($sql);

 $sql = 'UPDATE table SET password = ? WHERE record_id = ?';
 $prep = $mysqli->prepare($sql);
 $prep->bind_param('si', $pass, $record);

 while($row = $res->fetch_assoc()) {
      $pass = password_hash($row['password']);
      $record = $row['record_id'];
      $prep->execute();
 }