I found a solution to the problem referenced below that may help people using PHP PDO. I tested it and it works but I'm not sure it is the cleanest code or the best. Any improvements are welcome.
Here is the original problem for reference:
I want to hash passwords that are already in a MySQL database. I can already hash new passwords using the php 5.5 hashing API but I want to know if there is a way to take all the old plain text passwords and convert them to bcrypt hashes. I am thinking now of copying the passwords to a new row called 'hash' and, after checking that they copied correctly, convert them to hashes. I am not sure how to copy the password row and rename it on the same table, or how to hash all of these most efficiently, though.
Any insight would be appreciated.
Here is the solution:
<?
// 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;
?>