When storing passwords, the golden rule is to not store them in plain text. PHP provides several functions to hash the passwords.
md5() and sha1()
Hashing algorithms such as MD5 and SHA1 are very fast and efficient. Unfortunately with modern computers, it has become trivial to “brute force” the output of these algorithms to determine the original input.
Because of how quickly a modern computer can “reverse” these hashing algorithms, it is recommended to not use these hashing algorithms. Recommended functions include crypt() and password_hash()
Crypt
string crypt ( string $str [, string $salt ] )
crypt() will return a hashed string using the standard Unix DES-based algorithm or alternative algorithms that may be available on the system.
The salt parameter is optional. However, crypt() creates a weak password without the salt. PHP 5.6 or later raise an E_NOTICE error without it. It is strongly advise to specify a salt for improved security.
Password Hash
As of PHP 5.5, password_hash() creates a new password hash using a strong one-way hashing algorithm.
$password = "dY^543U%?%$";
$password = password_hash($password, PASSWORD_DEFAULT);
The second parameter passed in the function is the algorithm. The following algorithms are supported
The options supported for the PASSWORD_BCRYPT algorithm are:
An example of manually setting the salt and the cost can be seen below:
$options = [
'cost' => 11,
'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
];
echo password_hash("somepassword", PASSWORD_BCRYPT, $options);
The salt option has been deprecated as of PHP 7.0.0. It is now preferred to simply use the salt that is generated by default.
You can verify the hash using the password_verify() function.
$hash = password_hash("somepassword", PASSWORD_DEFAULT);
if (password_verify('somepassword', $hash)) {
echo 'Password is valid.';
} else {
echo 'Invalid password.';
}
You can retrieve the details of the password hash using the password_get_info() function:
$password = "somepassword";
$hash = password_hash($password, PASSWORD_DEFAULT);
print_r(password_get_info($hash));
// Prints: Array ( [algo] => 1 [algoName] => bcrypt [options] => Array ( [cost] => 10 ) )
The password_needs_rehash() function checks to see if the supplied hash implements the algorithm and options provided. If not, it is assumed that the hash needs to be rehashed.
The algorithm used by PASSWORD_DEFAULT is subject to change as different versions of PHP are released, so this function would be used here.
$password = 'somepassword';
$hash = '$2y$10$YCFsG6elYca568hBi2pZ0.3LDL5wjgxct1N8w/oLR/jfHsiQwCqTS';
// The cost parameter can change over time as hardware improves
$options = array('cost' => 11);
// Verify stored hash against plain-text password
if (password_verify($password, $hash)) {
// Check if a newer hashing algorithm is available
// or the cost has changed
if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options)) {
// If so, create a new hash, and replace the old one
$newHash = password_hash($password, PASSWORD_DEFAULT, $options);
}
// Log user in
}
Note: This article is based on PHP version 5.5.