How to Use PHP'S Password_Hash to Hash and Verify Passwords

How to use PHP's password_hash to hash and verify passwords

Using password_hash is the recommended way to store passwords. Don't separate them to DB and files.

Let's say we have the following input:

$password = $_POST['password'];

You first hash the password by doing this:

$hashed_password = password_hash($password, PASSWORD_DEFAULT);

Then see the output:

var_dump($hashed_password);

As you can see it's hashed. (I assume you did those steps).

Now you store this hashed password in your database, ensuring your password column is large enough to hold the hashed value (at least 60 characters or longer). When a user asks to log them in, you check the password input with this hash value in the database, by doing this:

// Query the database for username and password
// ...

if(password_verify($password, $hashed_password)) {
// If the password inputs matched the hashed password in the database
// Do something, you know... log them in.
}

// Else, Redirect them back to the login page.

Official Reference

Using password_hash and password_verify

On signup you get the password from the user input and generate its has using password_hash():

$hash = password_hash($_POST['password'], PASSWORD_BCRYPT);

You can provide it a custom salt to use, in a third parameter, but the documentation recommends to not do this:

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.

You save this hash in the database. Make sure you put it in a CHAR/VARCHAR field of 60 characters or longer.

When the user wants to log in you check the password they input against the hash previously saved using password_verify():

$auth = password_verify($_POST['password'], $hash);

Of course, you get the correct value of $hash from the database, searching by the provided username.

If $auth is TRUE then the provided password matches its hash computed on the registration and the user is authenticated.

How to verify two hashed password that were hashed with php's password_hash() function

You can't, period. That's the entire point of password_hash and its random salt: if you have two hashes, you don't know if they're for the same password. That prevents brute-forcing an entire database of hashes by an attacker, since the attacker can't amortise brute-force time invested into one hash by matching other hashes.

PHP password_hash(), password_verify()

Here is what I use for password_hash and password_verify. Try it out as written, you can then start adding in the rest of your code once successful.

Modify table and column name(s) to suit.

N.B.: This is a basic insertion method. I suggest you use prepared statements instead.

Sidenote: The password column needs to be long enough to accomodate the hash VARCHAR(255). Consult "Footnotes".

INSERT file

<?php
$DB_HOST = 'xxx';
$DB_USER = 'xxx';
$DB_PASS = 'xxx';
$DB_NAME = 'xxx';

$conn = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);
if($conn->connect_errno > 0) {
die('Connection failed [' . $conn->connect_error . ']');
}

$password = "rasmuslerdorf";
$first_name = "john";
$password = password_hash($password, PASSWORD_DEFAULT);

$sql = "INSERT INTO users (`name`, `password`) VALUES ('" .$first_name ."', '" .$password ."')";

$query = mysqli_query($conn, $sql);
if($query)

{
echo "Success!";
}

else{
// echo "Error";
die('There was an error running the query [' . $conn->error . ']');
}

LOGIN file

<?php
// session_start();

$DB_HOST = 'xxx';
$DB_USER = 'xxx';
$DB_PASS = 'xxx';
$DB_NAME = 'xxx';

$conn = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);
if($conn->connect_errno > 0) {
die('Connection failed [' . $conn->connect_error . ']');
}

$pwd = "rasmuslerdorf";
$first_name = "john";

//$sql = "SELECT * FROM users WHERE id = 1";

$sql = "SELECT * FROM users WHERE name='$first_name'";
$result = $conn->query($sql);
if ($result->num_rows === 1) {
$row = $result->fetch_array(MYSQLI_ASSOC);
if (password_verify($pwd, $row['password'])) {

//Password matches, so create the session
// $_SESSION['user'] = $row['user_id'];
// header("Location: http://www.example.com/logged_in.php");

echo "Match";

}else{
echo "The username or password do not match";
}

}

mysqli_close($conn);

Footnotes:

The password column should be long enough to hold the hash. 72 long is what the hash produces in character length, yet the manual suggests 255.

Reference:

  • http://php.net/manual/en/function.password-hash.php

"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)."

Hashing and verifying user in login form PHP

There's too much hashing here.

When registering a user you store the unhashed user name and the password hashed with password_hash()

When logging in you use the unhashed user name to recover the hashed password for that user, then use password_verify() to compare the unhashed password the user has given you with the hashed password you stored.

password_hash() adds a random salt to the password and stores the salt and the generated hash in the resulting string. Even if you hash the same password twice you'll get a different result each time.

How to use the encrypt password for login php

(By far the simplest method...)
Try this example. It uses Argon2, which is by far the safest encryption method (AFAIK)

Note that it randomly generates a different string when run, so using password_verify is mandatory unlike using sha-256 to look up the password in the database

<?php
$pwd = password_hash("my password goes here", PASSWORD_ARGON2I);
// Use $_POST instead
echo $pwd;
?>

And to verify your password:

if(password_verify($_POST['password'], $row["password"])) {
// Your code here...
}

Also, use PDP PDO, it's much safer against SQL injection attacks

<?php
$db = new PDO('mysql:host='.$servername.';dbname='.$dbname.';charset=utf8mb4', $username, $password);
try {
$query = "SELECT * from `login` WHERE `username`=:username OR `email` =:usernamea";
$stmt = $db->prepare($query);
$stmt->bindParam('username', $username, PDO::PARAM_STR);
$stmt->bindParam('usernamea', $username, PDO::PARAM_STR);
$stmt->execute();
$count = $stmt->rowCount();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if($count == 1 && !empty($row)) {
$auth_email = $row['email'];
$auth_pwd = $row['password'];
if(password_verify($_POST['password'], $auth_pwd)) {
$validuser = $row['username'];
$_SESSION['valid'] = $validuser;
$_SESSION['name'] = htmlspecialchars($row['name']);
}
else {
echo 'Invalid';
}
}
else {
echo 'Invalid';
}
}
catch (PDOException $e) { echo "Error : ".$e->getMessage(); }
?>


Related Topics



Leave a reply



Submit