6

I'm using PHP's password hashing API to hash and verify my passwords on a site I'm building, however whenever I try and verify my password it always returns false.

I have a User class which sets the password before they are inserted into the database:

public function set__password($passwd) {
    self::$password = password_hash($passwd, PASSWORD_BCRYPT, array('cost' => 12));
}

If the username and email is unique the new user row is inserted - upon checking my database I have what seems to be a valid BCRYPT string for my password:

$2y$12$lTMEP0wevDEMX0bzStzoyOEzOTIAi3Hyhd3nYjGwzbI

To verify my password, I run the following script:

$username = $_POST['username'];
$password = $_POST['password'];

$DB = Database::getInstance();

// Get the stored password hash
$res = $DB->run__query('SELECT password FROM users WHERE username = "' . $username . '"');
$hash = $res[0]['password'];


// Do the passwords match?
if(password_verify($password, $hash)) {
    echo 'success';
} else {
    echo 'failed';
}

$hash pertains to the string quoted above, however when I then call password_verify($password, $hash) where $password is the plain-text password retrieved from my input field, I always receive a value of false.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Halfpint
  • 3,967
  • 9
  • 50
  • 92
  • Is the `$hash` retrieved from the database the exact same value as the `self::$password` put into the database...? Typical problem: too short columns. – deceze Jul 14 '14 at 14:49
  • `PASSWORD_BCRYPT` requires a field length of 60 from what I've read, I set the column in the db to that so I don't think that should be the problem - I shall double check that though – Halfpint Jul 14 '14 at 14:51
  • 1
    Injection vulnerabilities... `$DB->run__query()`. Sure, it works with a username like _"bob"_, but it's no match for usernames like _`Bobby"; DROP TABLE users; --"`_, is it? – Elias Van Ootegem Jul 14 '14 at 14:51
  • @EliasVanOotegem good spot, I've used PDO blocks everywhere else - shall rewrite that – Halfpint Jul 14 '14 at 14:54
  • 1
    That pesky Bobby Tables. – Samsquanch Jul 14 '14 at 14:54

2 Answers2

19

The given hash string example has 50 characters instead of 60. Double-Check the database - CHAR(60) - and var_dump($hash).

Frank Liepert
  • 232
  • 3
  • 6
-6

Other problem that you can have, is when you reduce the cost in the server for gaining time.

Always use password_hash($pass, PASSWORD_DEFAULT), is the best way.

  • The PHP manual explicitly discourages the use of `PASSWORD_DEFAULT` as it may change over time and versions and leads to inconsistency. – Tala Apr 11 '20 at 06:06
  • Please add some explanation to your answer - "other problem" sounds a bit as your answer contains a solution for a problem that hasn't been stated in the question? – Nico Haase Apr 11 '20 at 21:27