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;
?>
- Am I doing this correctly?
- Should the salt be stored in databases as byte datatype?
- Should the final hash be stored at String datatype in database?
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.
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.If you are running
(PHP 5 >= 5.5.0)
then you can take advantage of the built-in php password hashing functionality.Simple usage:
normally I stored the salt with hashed password. I have my own format to recognize the salt form the hashed password. for example, the hashed password is 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824, and the salt is aaabbb. I append salt to hashed password like 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824aaabbb. So I can recognize the last 6 word is salt for this hashed password. Even the db has been hacked, they still didn't know the salt and the real password.