8

I am thinking of using password_hash() function to encrypt user passwords. I understand that this function generates salt by default if you don't provide it, and it is even encouraged to use the default salt instead of your own. I am currently weighing in 3 options and can't decide which one to go with so I'd appreciate it if you could help me out.

1. option: password_hash() with default salt

$passwordInput = $_POST['password'];
$passwordHash = password_hash($passwordInput, PASSWORD_BCRYPT);
//INSERT $passwordHash INTO DATABASE

2. option: password_hash() with custom salt

$options = ['salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)];
$passwordInput = $_POST['password'];
$passwordHash = password_hash($passwordInput, PASSWORD_BCRYPT, $options);
//INSERT $passwordHash INTO DATABASE

3. option: not using password_hash() at all

I am basing this option on a post from 2014: The definitive guide to form-based website authentication. Basically if it is a more secure approach than password_hash() I'd use something like this:

$salt = uniqid(rand(0, 1000000);
$passwordInput = $_POST['password'];
$password = hash('sha512', $salt . $passwordInput);
//INSERT $password AND $salt INTO DATABASE SEPARATELY
Community
  • 1
  • 1
Mario Plantosar
  • 766
  • 9
  • 21
  • 2
    Seem to remember reading in the changelog that the salt option has been deprecated completely in PHP7 - so it's probably best to use the salt that's generated automatically : http://php.net/manual/en/migration70.deprecated.php (near the bottom of the page) – CD001 Nov 12 '15 at 13:52
  • Option 3 is bad. SHA-512 without a KDF such as bcrypt is too fast. An attacker gaining access to the hashes can quickly run them through a password guessing attack. The article is wrong on this. – SilverlightFox Nov 24 '15 at 09:33

1 Answers1

12

The really short answer to this question is to use password_hash() with the default salt (your first option), custom salt is deprecated in PHP7 because, to quote php.net:

The salt option for the password_hash() function has been deprecated to prevent developers from generating their own (usually insecure) salts. The function itself generates a cryptographically secure salt when no salt is provided by the developer - therefore custom salt generation should not be needed.

By the same token, your third option, hash() should be avoided as again you'll need to generate your own salt.

CD001
  • 7,661
  • 2
  • 22
  • 27
  • This is fine but what confuses me is: If the system generates its own salt, WE don't know what the salt is. If we can't store the sale along with the password hash how can we ever check if a password posted is correct? Without knowing the salt we can't create the same hash again. – Ade Mar 18 '20 at 23:10
  • 1
    @Ade The salt *is* stored with the hash though, look at the [Return Values](https://www.php.net/manual/en/function.password-hash.php) section in the documentation:- *"The used algorithm, cost and salt are returned as part of the hash. Therefore, all information that's needed to verify the hash is included in it."* – CD001 Mar 19 '20 at 09:47
  • Thanks, yes, I did not initially see that there is also the function [password_verify()](https://www.php.net/manual/en/function.password-verify.php) - this handles it all. – Ade Mar 19 '20 at 21:29