3

UPDATE So this is an embarrassingly stupid admission, but the issue was that the hash I had stored in the database was a hash of 'password' including the quotes, there was no issue with the queries I wrote, the issue was between the chair and the keyboard.

So this is an often asked question, and I've looked all over stackoverflow and google trying to find out the answer, and have so fare been unsuccessful.

I have a table of "agents" with logins and password assigned to each agent. The password field is a varchar with a length of 255.

Here is my php code:

     $conn = new mysqli( "localhost", "VABEN", "**********", "VABen" );
     if( $conn->connect_error )
     {
        die( "Connection failed!" . $conn->connect_error );
     }
     $username = $_POST["username"];
     $password = $_POST["password"];

     $s = $conn->prepare( "SELECT `agent_password` FROM `VABen`.`agents` WHERE `agent_login`=?" );
     $s->bind_param( "s", $username );
     $s->execute();

     $hash = $s->get_result();
     $hash = $hash->fetch_array( MYSQLI_ASSOC );

     $testpw = password_hash( 'password', PASSWORD_DEFAULT );
     echo "Comparing submitted password to locally created hash $testpw which has a length of " . strlen($testpw) . "<br>";
     if( password_verify( $password, $testpw ) )
     {
        echo "Password '$password' matches with hash $testpw<br>";
     }
     else
     {
        echo "Password '$password' does not match with hash $testpw<br>";
     }
     echo "<br>";

     echo "Supplied Password: '$password'<br>";
     echo "Queried Hash: " . $hash['agent_password'] . " which has a length of " . strlen( $hash['agent_password'] ) . "<br>";
     echo "Result of password_verify: ";
     if( password_verify( $password, $hash['agent_password'] ) )
        echo "true<br>";
     else
        echo "false<br>";

I am at a loss. It only seems to work when I supply a locally created copy of password_hash, and if I then use that locally created copy in the MySQL database, it fails.

Any ideas?

Will Sayin
  • 43
  • 5
  • And to clarify, password_verify returns true when I supply a locally made copy of password_hash, but not when I supply a hash pulled from a MySQL table. – Will Sayin Nov 20 '14 at 20:45
  • So the test with `$testpw` works right? Then I can only think of saving the hash to the database goes wrong somehow. What happens when you save `$testpw` first, and then select that record from the database? – redelschaap Nov 20 '14 at 21:59
  • @ircmaxell-- password_verify returns false when, from what I can see, it should return true. – Will Sayin Nov 20 '14 at 23:56
  • @Ronald01990-- $testpw works, it holds a hash of 'password' using the password_hash function. I will see if I can insert a new login and then immediately test it next. – Will Sayin Nov 20 '14 at 23:58

1 Answers1

1

Store the hash

Have you checked that agent_password is storing a hash generated by:

password_hash( $password, PASSWORD_DEFAULT );

Check PDO standards

Probably has no effect, but it is worth following standards for the differnt implementations of bindParam. If you're using the ? method, then:

 $s->bind_param( 1, $username );

There are several odd implementations of PDO in your script, try adjusting:

 $s->execute();

 //$hash = $s->get_result();
 //$hash = $hash->fetch_array( MYSQLI_ASSOC );
 $hash = $s->fetchColumn();

Change subsequent calls of $hash['agent_password'] to just $hash instead.

Test Basic Operation

Test the folowing:

// $password = $_POST["password"];
$password = "password";

Then, also try storing that hash, and retrieving it again, from mysql, prior to the final verify step.

Finally

I deeply suspect that what is stored in agent_password is not in fact a password hashed with password_hash.

Tony Chiboucas
  • 5,145
  • 1
  • 25
  • 35
  • This is the output from what I have above: `Comparing password to locally created hash $2y$10$NrTgd5b.qVnhs.smiZemHOQWM8PQ8q11Sfiyw1Bm1Wex6t3qpE6aa which has a length of 60` `` `Password 'password' matches with hash $2y$10$NrTgd5b.qVnhs.smiZemHOQWM8PQ8q11Sfiyw1Bm1Wex6t3qpE6aa` `Supplied Password: 'password'` `` `Queried Hash: $2y$10$668gODHJ14N7Z6i17lboLOHBQ6mkdxz3g99brUoeoxRBHSeri80ZK which has a length of 60` `` `Result of password_verify: false` – Will Sayin Nov 21 '14 at 00:00
  • Well there you have it. Supplied password does not match the stored hash of the password. Perhaps `PASSWORD_DEFAULT` changed since that password was created? – Tony Chiboucas Nov 21 '14 at 00:05
  • Do you have the original password for that user? – Tony Chiboucas Nov 21 '14 at 00:06
  • Yeah, you are correct, I put it in my main post too, but what I had done was hashed 'password' _with_ the quotes, so it was hashing "'password'" instead of "password" – Will Sayin Nov 21 '14 at 00:18
  • Ha! It always ends up coming down to the simple things doesn't it. I'm glad you've gotten it figured out, sorry you had to spend so much time on it. You're certainly not alone in mistakes like that one. – Tony Chiboucas Nov 21 '14 at 00:36