-1

I'm working on a login page and the password_verify() always returns false when getting the hash from the DB but prints true when using static values Here's my code :

<?php
require_once "ID.php";

$message = "";

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    // Connect to the database
    $conn = new mysqli($DB_SERVER, $DB_USER, $DB_PASSWORD, $DB_NAME);
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }

    $pseudo = $_POST['pseudo'];
    $passwordInput = trim($_POST['password']);

    // Fetch the stored password hash
    $stmt = $conn->prepare("SELECT password FROM users WHERE Pseudo = ?");
    $stmt->bind_param("s", $pseudo);
    $stmt->execute();
    $stmt->bind_result($storedHash);
    $stmt->fetch();

    // Debugging: Output the fetched stored hash and length
    echo "Stored Hash: $storedHash<br>";
    echo "Stored Hash Length: " . strlen($storedHash) . "<br>";

    // Check if we found the user
    if ($storedHash) {
        // Debugging: Check if password verification passes
        $verifyResult = password_verify($passwordInput, $storedHash) ? "true" : "false";
        echo "Password verify result: $verifyResult<br>";

        if (password_verify($passwordInput, $storedHash)) {
            $message = "Login successful!";
        } else {
            $message = "Invalid username or password.";
        }
    } else {
        $message = "User not found.";
    }

    $stmt->close();
    $conn->close();
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
    <h2>Login</h2>
    <?php if ($message) echo "<p>$message</p>"; ?>
    <form method="POST" action="">
        <input type="text" name="pseudo" placeholder="Username" required><br>
        <input type="password" name="password" placeholder="Password" required><br>
        <button type="submit">Login</button>
    </form>
</body>
</html>

I tried using static values and it worked but the second its not static it doesn't work anymore

4
  • 3
    Without checking your code, I can say that the most common reason for this to occur is that the storage space in the database is too short for the hash of the password. As they say in the manual: 255 characters would be a good choice. What did you use? Commented Feb 8 at 13:36
  • That's correct. For testing, extract the generated hash without storing it, and then compare it with the stored value. You can also paste it into the following small playground; the verify function should work fine: password_verify() playground Commented Feb 8 at 13:40
  • 2
    Then something that just annoys me. You call the password hash in your PHP code $storedHash. That's a reasonable name: It's a hash, and it came from the database. I would have preferred $passwordHash, which is a more accurate description of the value. But in your database you call it password. It's not a password, and that name looks nothing like $storedHash. What is it? A password or a hash? See, if you call them both passwordHash, in your database and your PHP code, you can instantly see what's what. Choosing names is hard, I know. Commented Feb 8 at 13:42
  • Please never die() and print raw query errors. Please never trim() passwords. Why do you call password_verify() twice when once is enough? What are the column details. This question Needs Debugging Details. Commented Feb 8 at 21:53

1 Answer 1

1

First of all, make sure your passwords in the database are actually password hashes and that they were hashed via password_hash. If you did not hash them or did not use this way to hash them, then your password validation is incompatible with the way passwords and password hashes are being stored in your database.

The documentation warns you that if you use PASSWORD_BCRYPT as the algorithm then your password is truncated to 72 characters before being hashed.

The first parameter is your password string, the second is the algorithm and the third is the options. These are possible algorithms to choose from

PASSWORD_DEFAULT - Use the bcrypt algorithm (default as of PHP 5.5.0). Note that this constant is designed to change over time as new and stronger algorithms are added to PHP. For that reason, the length of the result from using this identifier can change over time. Therefore, it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice).

PASSWORD_BCRYPT - Use the CRYPT_BLOWFISH algorithm to create the hash. This will produce a standard crypt() compatible hash using the "$2y$" identifier. The result will always be a 60 character string, or false on failure.

PASSWORD_ARGON2I - Use the Argon2i hashing algorithm to create the hash. This algorithm is only available if PHP has been compiled with Argon2 support.

PASSWORD_ARGON2ID - Use the Argon2id hashing algorithm to create the hash. This algorithm is only available if PHP has been compiled with Argon2 support.

and among the options you may have a salt or other specified elements that alter the hash from the unmodified result.

password_verify in its second parameter passes the cost and salt too.

You can try running

password_verify($rawPassword, password_hash($rawPassword, $algo, $options))

and it should always be true. So try this with your test-case. If it's not matching, then you found errors in the PHP functions that you call. If they are matching, then you do not properly pass the hash and will need to carefully check what you pass, or the password was simply incorrect.

Sign up to request clarification or add additional context in comments.

4 Comments

thanks yeah my DB didn't have enough value storage
Welcome to Stack Overflow @MaxLhrm - stackoverflow.com/help/someone-answers
Small correction: bcrypt truncates the password to 72 characters, before hashing it. That happens consistently on both hash and verify, so would never cause a login attempt to fail, it would cause multiple long passwords to all succeed if they are different only after the 72nd byte.
@IMSoP thanks for pointing that out, edited my answer accordingly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.