Why Is Password_Verify Returning False

PHP password_verify returning false

You overwrite your $password when you include your dbconnection.

include('connection.php');

has:

$password="mypassword";

Previously you set:

$password=validateFormData($_POST['password']);

so your hashed password is not the user's password, but your DB password.

I would prefix all DB credentials variables with db_. So your database password variable would then be $db_password. This will allow you to have distinct variables throughout your project (I'd think).

Additionally you should be using $formPass, not $newpass. The $newpass is going to be double hashed at the verify function.

$formEmail=validateFormData($_POST['loginEmail']);
$formPass=validateFormData($_POST['loginPassword']);
$newPass=password_hash($formPass,PASSWORD_DEFAULT);

so change:

if(password_verify($newPass,$LogPass))

to:

if(password_verify($formPass, $LogPass))

Why does password_verify return false?

There are a variety of reasons why password_verify could be returning false, it can range from the setup of your table to the actual comparing of the password, below are the common causes of it failing.

Column Setup

  • The length of the password column in your table is too short:

    • If you are using PASSWORD_DEFAULT then it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice).
    • If you are using PASSWORD_BCRYPT then it is recommended to store the result in a database column that is 60 characters because PASSWORD_BCRYPT will always result in a 60 character string or FALSE on failure.

Password Sanitization

Another common cause is when developers try to "clean" the user's password to prevent it from being malicious, as a result, this causes the input to be different to what is being stored in the table. It is not even necessary to escape the input, you should use prepared statements instead. You shouldn't even trim the passwords as that could change that which was originally provided.

Password Verification

When using password_verify you need to compare the plaintext password with the hash from the database/file/some-other-storage-method, not compare hashes (the implication here being that you need to have stored the hashed password of the user when they register):

<?php

$hashed = password_hash('test', PASSWORD_DEFAULT);
$password = 'test';

if (password_verify($password, $hashed)) {
echo 'success';
} else {
echo 'fail';
}

?>

Ensure that you are actually passing a hash to password_verify and not something else by dumping it.

Repl

Hardcoded Passwords

In the instance that you are using a hardcoded hash and you are facing issues, ensure that you are using single quotes instead of double quotes when storing the value in the variable as the $ will be interpreted in when using double quotes:

<?php
// Undefined variable: QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu :1
$incorrect = "$2y$10$QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu";

$correct = '$2y$10$QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu';
?>

Repl - Comment out respectively.

Troubleshooting

var_dump() the hashed password on registration right before you insert it into your database, and var_dump() it again after you fetch it from your database when you are about to password_verify() it. Ensure both hashes are identical. If they are, and the plaintext passwords are identical too, there's no reason for password_verify to fail. It only fails if the hash gets modified in some way on its roundtrip through the database, or if the plaintext passwords aren't identical.

Ensure that you are passing a correct algorithm to password_hash has the second parameter.

Addendum

As per the documentation:

Caution It is strongly recommended that you do not generate your own salt for this function. It will create a secure salt automatically for you if you do not specify one.

As noted above, providing the salt option in PHP 7.0 will generate a deprecation warning. Support for providing a salt manually may be removed in a future PHP release.

PHP password_verify always returning false even when hardcoded

I could not find any problem in your code here but since hashing and verifying is a process which depends on a lot of factors to be successful i would like to give you some tips so that you can check it yourself for any potential problems.

  1. make sure you are not escaping/sanityzing the password before
    hashing it. This way you're altering the stored password. Let

    $password = $_POST['password'];

both when you create the account and
when you check if the password match at login.


  1. make sure you are enclosing the hash variable in single quotes (') and not double quotes (").using double quotes makes PHP read each paired character with "$" as indivisual variables which will probably cause your code to break, USE SINGLE QUOTES INSTEAD.

  2. Ensure the Password field in the database (that stores the hashed
    password) is able to store up to 255 characters. From the documentation
    it is recommended to store the result in a database column that can
    expand beyond 60 characters (255 characters would be a good choice). If the field is narrower the hash will be truncated and you'll never
    have a match.

  3. As you get the user by username at login ensure that username is unique
    as long as it is your primary key (in the table
    definition). Good idea to check this also upon user registration and login (at php level).

  4. echo both hash and entered
    values and make sure they match the ones that were inserted and
    generated during password_hash() if the database value was different
    (the hash), make sure the type of its column is varchar(256), the
    hash is usually 60 characters long but the hashing function is
    frequently improved so that length may expand in the future.

  5. if the entered value was different (the user password), make sure the
    filtering isn't corrupting the password value.

  6. also check if another variable has the same name as the one you're storing the password in.

  7. If password_verify($password, password_hash($password, PASSWORD_DEFAULT))
    "works", then the problem is that $row['Password'] does not contain what is expected - including not being generated correctly.

  8. If it "doesn't work" then
    another line is causing the observed behavior. Both of these
    outcomes allow focusing on a refined problem set.

  9. try changing the password from the another column that matched and copy it to your password column and enter that password to check.if it worked then there is problem with your stored password

  10. try copying this hash to your password column

    $2y$10$uDnEpQpkh9RO5tWwOrHtneLAuYMRDstRaKGZFyHubObDR0789OMO6

this is the hashed password for 123456 using bycrypt. select this password and try to verify it with password_verify(123456,$yourhashedfromdatabase) after selecting this from sql if it works then there is probably some manipulation after your data is entered and goes to the database. it it does not then check if the password that reaches the database is exactly as your typed by echoing it.

UPDATE: after you updated your code i see that while entering the password you use "Pass" column but while extracting you use "Password" column. this could be the issue

password_verify() returning false when passwords match

password_verify() works with the function password_hash();

change:

$hash = hash('sha512', $password);

to:

$hash = password_hash($password, PASSWORD_DEFAULT);

Why my password hash is returning false when i provide the correct password?


  1. Messing with input is dangerous, you may be effecting the content of userid by using strip_tags and its unnecessary anyway if you use prepared queries.

  2. using var_dump() in this line if(var_dump(password_verify($password, $hash_password))){ will cause a false all the time as var_dump() returns NULL.

  3. It is also a good idea to add some error checking to the sqlsrv_ calls.

So suggested code amendments

if(isset($_POST['login'])) {

//$username = strip_tags(trim($_POST["username"]));
//$password = $_POST["password"];

$query = "SELECT * FROM USERNAME WHERE user_id= ?";
$params = array($_POST["username"]);
$stmt = sqlsrv_prepare($conn, $query, $params);
if( !$stmt ) {
print_r( sqlsrv_errors(), true);
exit;
}

if( sqlsrv_execute( $stmt ) === false ) {
print_r( sqlsrv_errors(), true);
exit;
}

$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);

//$hash_password = $row['password'];
//$new = password_verify($password, $hash_password);
//if(password_verify($password, $hash_password)){

if(password_verify($_POST["username"], $row['password']))){
$msg = "Login Success";
}else{
$msg = "Login failure";
}
echo $msg;
}

Of course the other thing to check is that the hashing of the password worked correctly, ass if that failed you will never get the verify to work.

password_verify Always Returns False, even with proper variables used

You are escaping your password, as a result this changes the password from what it was. Instead of relying on escaping as a security measure (which in itself is a misconception), use prepared statements.

As per the comment below, a clarification is required it seems: You are escaping the password then hashing it, as a result what is stored in the db is not what the user passes therefore it will never find what the user passes, hence, false is always returned.

Related: Should I mysql_real_escape_string the password entered in the registration form?

Update #1

As spotted by @mario, you seem to have spaces in your query when you are passing the values to it as such, it is searching your table for incorrect values.

Reading Material

Prepared Statements



Related Topics



Leave a reply



Submit