Hashing passwords with md5 (or sha1, or even sha256) is not safe anymore, because these hashes can be decrypted very easily.This is still not good enough though (rainbow tables). PHP 5.5+ came with a password_hash function to generate secure, one-way hashing along with a password_verify function to match a hashed password with the given password. For a developer security is always a priority so you should always be securely storing user passwords. We has passwords due to security concern and information leakage concern. If we store passwords in plain text then it can be compromised of information very easily.
PASSWORD_DEFAULT, PASSWORD_BCRYPT and (as of PHP >= 7.2.0) PASSWORD_ARGON2I are the password hashing algorithm options. Currently, the options PASSWORD_DEFAULT and PASSWORD_BCRYPT will both result in the use of the BCRYPT hashing algorithm, making them essentially the same.
1
2
3
4
5
6
7
8
9
|
<?php
/**
* PHP just want to hash our password using the current DEFAULT algorithm.
* This is presently BCRYPT, and will produce a 60 character result.
*
* Beware that DEFAULT may change over time, so you would want to prepare
* By allowing your storage to expand past 60 characters (255 would be good)
*/
echo password_hash("coding4developers", PASSWORD_DEFAULT);
|
PASSWORD_BCRYPT will create the hash of 60 characters.
PASSWORD_DEFAULT will also create the hash of 60 characters because currently it is also using BCRYPT hashing algorithm but if you are using PASSWORD_DEFAULT then it is recommended that keep database column size of 255 characters because this constant(PASSWORD_DEFAULT) is designed to change over time as new and stronger algorithms are added to PHP.
Another important option to mention is the cost, which controls the hash speed. It's recommended to test the cost before on your server before using it on productions.On servers with better resources, cost can be increased.It's good security practice is to try increasing this to a higher value than the default (10).
1
2
3
4
5
6
7
8
9
|
<?php
/**
* In this case, we want to increase the default cost for BCRYPT to 12.
* Note that we also switched to BCRYPT, which will always be 60 characters.
*/
$options = [
'cost' => 12,
];
echo password_hash("coding4developers", PASSWORD_BCRYPT, $options);
|
It is strongly recommended that you do not generate your own salt for this function. It will create a secure salt automatically for you if you do not specify one.
You also can use a randomly generated salt to hash the password like:
1
2
3
4
5
6
7
8
9
10
11
|
/**
* Note that the salt here is randomly generated.
* Never use a static salt or one that is not randomly generated.
*
* For the VAST majority of use-cases, let password_hash generate the salt randomly for you
*/
$options = [
'cost' => 11,
'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
];
echo password_hash("coding4developers", PASSWORD_BCRYPT, $options);
|
If you are using PHP >= 7.2.0 you also have option to use PASSWORD_ARGON2I. PASSWORD_ARGON2I uses Argon2 algorithm to hash the passwords.
1
2
|
<?php
password_hash('coding4developers', PASSWORD_ARGON2I);
|
PHP 5.5+ also provides a function to match the hashed password with the original password. You can verify the password which is hashed with the original password like:
1
2
3
4
5
6
7
8
|
<?php
$password_string = "coding4developers";
$password_hash = '$2y$12$jH5VaKfQZMZdgHkv.kYD1uSRFfAeaPbOs.VEcq5G2XB9vJtjsWaxm';
if (password_verify($password_string, $password_hash)) {
echo 'Correct password';
} else {
echo 'Incorrect password';
}
|