Search code examples
phpsecurityhashsalt-cryptography

Correct way of creating salted hash password


I am new to storing passwords on databases and from what I read I have created a simple php script below

<?php
  $salt =  openssl_random_pseudo_bytes (16);
  $password = "test";
  $hash = hash ("sha512" , $salt . $password);

  echo $hash;
?>
  1. Am I doing this correctly?
  2. Should the salt be stored in databases as byte datatype?
  3. Should the final hash be stored at String datatype in database?

Solution

  • The SHA* algorithms are not appropriate to hash passwords, because they are ways too fast, and therefore can be brute-forced too fast. Instead one should use a slow algorithm like BCrypt or PBKDF2 with a cost factor, which controls the necessary time.

    PHP supports the BCrypt algorithm with the new function password_hash(). There also exists a compatibility pack for earlier PHP versions.

    // Hash a new password for storing in the database.
    // The function automatically generates a cryptographically safe salt.
    $hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
    
    // Check if the hash of the entered login password, matches the stored hash.
    // The salt and the cost factor will be extracted from $existingHashFromDb.
    $isPasswordCorrect = password_verify($password, $existingHashFromDb);
    

    It is recommended that you do not pass your own salt, instead let the function create a cryptographically safe salt from the random source of the operating system.

    The salt will be included in the resulting hash-value, so you don't have to store it separately. Just create a 60 character string field in your database and store the hash-value. The function password_verify() will extract the used salt from the stored hash-value. For more information you can have a look at my tutorial about storing passwords.