【问题标题】:Php 5.5 hash API and hashing plain text passwords already in a database [closed]数据库中已经存在的 PHP 5.5 哈希 API 和哈希纯文本密码 [关闭]
【发布时间】:2014-12-31 11:15:41
【问题描述】:

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

这里是原始问题供参考:

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

任何见解将不胜感激。

解决方法如下:

    <?
    // 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;

?>

【问题讨论】:

  • 没有。哈希=绞肉机。哈希将一头牛变成汉堡包。没有办法把汉堡包拿回去变回原来的牛。您必须让您的用户重新输入他们的密码,以便他们可以通过新的哈希值运行。
  • @MarcB 我认为他所指的密码已经是纯文本。
  • 啊,好吧……在那种情况下update yourtable set new_hash = hash(old_password_field)。你可以做一个就地set pw=hash(pw),但是你会丢失原始的明文。
  • 嗨 MarcB,我可以在 phpmyadmin 中运行上述 SQL 查询并在新的“哈希”行中获取我的密码的哈希值吗?这就是我基本上想做的事情。

标签: php mysql sql hash passwords


【解决方案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();
 }

【讨论】:

  • 谢谢,但是如果它们已经在数据库中,我如何通过哈希传递它们?是否有一个 SQL 查询可以同时对所有密码执行此操作?当用户添加他们的数据时,我对 php 脚本对密码进行哈希处理感觉非常好,但是我如何获取数据库中已有的内容并通过 php 5.5 哈希 API 运行密码?密码是纯文本的(根本没有散列)。
  • 我用你可以使用的循环更新了它。没有更简单的方法,因为您不能将 PHP 混合到这样的 INSERT SELECT 语句中。如果您想打破循环,只需将WHERE password NOT LIKE "$%" 添加到您的初始查询中,然后一遍又一遍地运行它,直到所有内容都更新
  • 谢谢 Machavity,但我收到以下代码错误,我不太确定这意味着什么:“致命错误:在非对象……”这是指什么?谢谢,
  • 在我的例子中,$mysqli 是一个instance of the mysqli object
  • 感谢您的帮助,但我找到了一种适用于 PDO 的方法。我很难让它与 mysqli 一起工作,因为我对它的经验较少。如果我的解决方案对其他人有用,我可以在哪里发布它?
猜你喜欢
  • 2014-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-23
  • 2011-06-10
  • 2016-02-06
相关资源
最近更新 更多