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.
// 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.
If you are running (PHP 5 >= 5.5.0)
then you can take advantage of the built-in php password hashing functionality.
- http://php.net/manual/en/function.password-hash.php
- http://php.net/manual/en/function.password-verify.php
Simple usage:
$options = [
'cost' => 11,
'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM), // or your own salt here
];
$pass_hash = password_hash("helloworld", PASSWORD_BCRYPT, $options);
if (password_verify('helloworld', $pass_hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
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.
来源:https://stackoverflow.com/questions/24862499/correct-way-of-creating-salted-hash-password