Php salt hash password tutorial

How to increase hash security

The hash generated by password_hash() is very secure.

But you can make it even stronger with two simple techniques:

  1. Increasing the Bcrypt cost.
  2. Automatically updating the hashing algorithm.

Bcrypt cost

Bcrypt is the current default hashing algorithm used by password_hash().

This algorithm takes an option parameter named “cost”. The default cost value is 10.

By increasing the cost, you can make the hash more difficult to compute. The higher the cost, the longer the time needed to create the hash.

A higher cost makes more difficult to break the hash. However, it also makes the hash creation and check longer, too.

So, you want to find a compromise between security and server load.

This is how you can set a custom cost value for password_hash():


/* Password. */
$password = 'my secret password';

/* Set the "cost" parameter to 12. */
$options = ['cost' => 12];

/* Create the hash. */
$hash = password_hash($password, PASSWORD_DEFAULT, $options);

But what cost value should you set?

A good compromise is a cost value that lets your server create the hash in about 100ms.

Here is a simple test to find this value:


/* 100 ms. */
$time = 0.1;

/* Initial cost. */
$cost = 10;

/* Loop until the time required is more than 100ms. */
do
{
  /* Increase the cost. */
  $cost++;
  
  /* Check how much time we need to create the hash. */
  $start = microtime(true);
  password_hash('test', PASSWORD_BCRYPT, ['cost' => $cost]);
  $end = microtime(true);
}
while (($end - $start) < $time);

echo 'Cost found: ' . $cost;

Once you have found your cost, you can use it every time you execute password_hash() like in the previous example.

Keeping your hashes up to date with password_needs_rehash()

To understand this step, let’s see how password_hash() works.

password_hash() takes three arguments:

  1. The password you need to hash
  2. The hashing algorithm you want to use
  3. An array of options to pass to the hashing algorithm

PHP supports different hashing algorithms, but you usually want to use the default one.

You can select the default algorithm by using the PASSWORD_DEFAULT constant, as you have seen in the previous examples.

As of June 2020, the default algorithm is Bcrypt.

However, PHP can change the default algorithm in the future, if a better and more secure algorithm is implemented.

When that happens, the PASSWORD_DEFAULT constant will point to the new algorithm. So, all the new hashes will be created using the new algorithm.

But what if you want to take all your old hashes, made with the previous algorithm, and automatically create them again with the new one?

This is where password_needs_rehash() comes into play.

This function checks if a hash has been created with a given algorithm and parameters.

For example:


/* Password. */
$password = 'my secret password';

/* Set the "cost" parameter to 10. */
$options = ['cost' => 10];

/* Create the hash. */
$hash = password_hash($password, PASSWORD_DEFAULT, $options);

/* Now, change the cost. */
$options['cost'] = 12;

/* Check if the hash needs to be created again. */
if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options))
{
  echo 'You need to rehash the password.';
}

If the current default hashing algorithm is different from the algorithm used to create the hash, password_needs_rehash() returns true.

password_needs_rehash() also checks if the options parameter is different.

This is very handy if you want to update your hashes after you change a parameter like the Bcrypt cost.

This example shows how you can automatically check a password hash and update it if needed, when a remote user logs in:


/* Include the database connection script. */
include 'pdo.php';

/* Set the "cost" parameter to 12. */
$options = ['cost' => 12];

/* Login status: false = not authenticated, true = authenticated. */
$login = FALSE;

/* Username from the login form. */
$username = $_POST['username'];

/* Password from the login form. */
$password = $_POST['password'];

/* Remember to validate $username and $password. */

/* Look for the username in the database. */
$query = 'SELECT * FROM accounts WHERE (account_name = :name)';

/* Values array for PDO. */
$values = [':name' => $username];

/* Execute the query */
try
{
  $res = $pdo->prepare($query);
  $res->execute($values);
}
catch (PDOException $e)
{
  /* Query error. */
  echo 'Query error.';
  die();
}

$row = $res->fetch(PDO::FETCH_ASSOC);

/* If there is a result, check if the password matches using password_verify(). */
if (is_array($row))
{
  if (password_verify($password, $row['account_passwd']))
  {
    /* The password is correct. */
    $login = TRUE;
	
	/* Check if the hash needs to be created again. */
    if (password_needs_rehash($row['account_passwd'], PASSWORD_DEFAULT, $options))
    {
      $hash = password_hash($password, PASSWORD_DEFAULT, $options);
      
      /* Update the password hash on the database. */
      $query = 'UPDATE accounts SET account_passwd = :passwd WHERE account_id = :id';
      $values = [':passwd' => $hash, ':id' => $row['account_id']];
      
      try
      {
        $res = $pdo->prepare($query);
        $res->execute($values);
      }
      catch (PDOException $e)
      {
        /* Query error. */
        echo 'Query error.';
        die();
      }
    }
  }
}

What is salt and hashing PHP?

Salting and hashing is a technique to store the password in a database. In cryptography, salting means to add some content along with the password and then hashing it. So salt and hash provide two levels of security.

What is the most used method for hashing passwords in PHP?

In PHP, there are various cryptographic algorithms that are commonly used like md5, crypt, sha1, and bcrypt. And the most commonly used nowadays is bcrypt hashing method.

Is PHP password hash secure?

PHP provides a native password hashing API that safely handles both hashing and verifying passwords in a secure manner.

What is a salt in a password hash?

A salt is a piece of random data added to a password before it is hashed and stored. Adding a salt to stored passwords is a security process used alongside the hashing of passwords before they are stored.