3

today we have updated our PHP from 5.5.7 to 5.6.13 and all password hashes from password_hash() function have stopped working.

Is there any information on why this occurred? What have we done wrong?

When I've used password reset functionality to create new hash of the password it then worked correctly again.

Passwords are stored in MySQL database using varchar(255). Class used is Passwords.php

Authentication looks like this:

// Try to find the user from database
$user = $this->getUser($email);

// If the provided password is invalid
if (!isset($user) || !$user->isPasswordValid($password)) {
    throw new AuthenticationException('portal.user.signInFailed');
}

And the isPasswordValid method looks like this:

/**
 * Validate given User password.
 * @param  string  $value  Password to validate
 * @return bool
 */
public function isPasswordValid($value)
{
    return Passwords::verify($value, $this->password);
}

This is how my hashing function looks like:

/**
 * Set and hash new password value.
 * @param  string  $value  New password
 * @return static
 */
public function setPassword($value)
{
    $this->password = Passwords::hash($value);
    return $this;
}

This is hash from before update (not working) and after password reset(working)

$2y$10$wMM1rXjwOIJb8Ga0L0mINevOvZxY4C2ebucBDNZ1P1dkp.J22KGzm
$2y$10$cr6HeWoS2MDxK1tbJvaEjefMiex1RgeG/JrHTrVznN2DeBPVJnVC.

I'd rather not give you the password itself :)

  • Clearly the hashing algorithm used changed between versions, so the stored hashes are no longer the same as the newly generated hashes. – adeneo Oct 25 '15 at 14:26
  • Well, we hardly can answer if you don't post the code, can we? – arkascha Oct 25 '15 at 14:26
  • Here's a list of updates btw -> http://php.net/manual/en/migration56.new-features.php – adeneo Oct 25 '15 at 14:26
  • Well if it helps I am using this class [Passwords.php](https://github.com/nette/security/blob/master/src/Security/Passwords.php) – Martin Procházka Oct 25 '15 at 14:36
  • @adeneo - Wouldn't make any difference to password verify().... the hash identifies the algorithm used, the cost, and the seed, so even if the arguments/defaults for password() hash change, verify knows the actual values used – Mark Baker Oct 25 '15 at 14:36
  • If possible can you give the password hash of the same string for before and after? Please post the class information in your answer because without more information your question is going to get downvoted. – Elin Oct 25 '15 at 14:39
  • Are you passing in any options (e.g. $options['cost']? – Elin Oct 25 '15 at 14:42
  • @Elin nope all is default. – Martin Procházka Oct 25 '15 at 14:44
  • @MarkBaker - that's true, and it does seem strange? The OP is using a custom class, but it looks to be just a wrapper around the password_* functions, so there shouldn't be any issues with this at all ! – adeneo Oct 25 '15 at 14:57
  • @adeneo yes it is just a wrapper to handle errors properly. – Martin Procházka Oct 25 '15 at 15:00
  • Read this http://stackoverflow.com/questions/1581610/how-can-i-store-my-users-passwords-safely Are you expecting the hash to be the same? It shouldn't be unless you specify the salt. Are you saying that verification is not working? – Elin Oct 25 '15 at 15:00
  • @Elin Verification of the first hash does fail, verification of second hash passes, it is a hash with same options, same password just one is created before update and second after update. – Martin Procházka Oct 25 '15 at 15:04
  • So I was trying this at https://3v4l.org/TnMr4 and it seems to work, which makes me think there is something in how the code is called such as whether the cost is changing unintentionally (I notice that the library has deprecated its assignment of a default cost). updated the link to the right one. – Elin Oct 25 '15 at 15:29
  • @Elin I get that it works, I also know that it is supposed to, I just don't get why my hashes stopped working. That deprecated constant is really old, even before I started using this class. – Martin Procházka Oct 25 '15 at 15:36
  • I know, I'm just thinking it through step by step and verifying that it actually does work when using the core method. And you are positive that `$value` is being passed correctly because it is working once you rehash. So it really has to be something about how the hashes were previously created. But you were using the same library so that should not have changed unless something ancillary changed. Which is why I asked about the options. – Elin Oct 25 '15 at 15:43
  • This might sound a bit strange, and I don't at all see how it comes into play, but password_verify() will return false if somehow the string is double quoted. But that is true for all versions of PHP. Your code didn't change so it should not be a problem. I don't see how that would have changed unless there was some terrifying change in PHP that would certainly have caused a lot of other problems. – Elin Oct 25 '15 at 16:16
  • @Elin Well the hash is loaded from database using Doctrine ORM, there is no double-quoting. I have those hashesh in dumb-down script just to test it using the core method and it still gives me false for pre-update hash. Thing is, I've updated PHP, not the framework itself. – Martin Procházka Oct 25 '15 at 16:39
  • @Elin Seems like hashes of others do work normally, just my password doesn't :X – Martin Procházka Oct 25 '15 at 16:56
  • 2
    I would look for the problem somewhere else: 1) Maybe you use UTF-8 characters in your password and the encoding of the page has somehow changed. 2) Make sure you don't have any preceeding/trailing whitespaces in password and hash. 3) The size of the database field is often too short, but it seems to be ok in your case. – martinstoeckli Oct 25 '15 at 20:11

0 Answers0