Reputation: 7935
I found the following example on php.net to secure password before storing it. However, I don't quite understand line 3. Could someone explain this a little bit? Thanks!
1 <?php
2 $password = crypt('mypassword'); // let the salt be automatically generated
3 if (crypt($user_input, $password) == $password) {
4 echo "Password verified!";
5 }
6 ?>
Upvotes: 2
Views: 2760
Reputation: 868
The second parameter is the key. That accepts either nothing, a salt, or a hash that crypt
made earlier, which has the salt to make the hash, embedded in it. In the first case, a salt is made up. In the latter case, the salt is used and not the entire hash. So therefore this holds (make sure you understand that, because that's the key to understanding line 3):
crypt($input, $salt) == crypt($input, crypt($input, $salt))
What you have in your database as the user's hashed password, is the left term in that equation. So line 3 can be rewritten as:
if (crypt($user_input, crypt('mypassword')) == crypt('mypassword'))
And the salt was automatically generated in line 2, let's assume it equals 'autosalt'. Line 3 can now be rewritten to this:
if (crypt($user_input, crypt('mypassword', 'autosalt')) == crypt('mypassword', 'autosalt')
And there you go: this is only true if $user_input == 'mypassword'
.
Upvotes: 0
Reputation: 6335
crypt is a one-way function and returns a string that already contains the salt,
When comparing the user input with the crypt result, the function automatically extracts the salt from the string.
To be more clear :
crypt() outputs a string that contains both the salt and the result of the hash. When you pass it that string as a salt, it knows to extract only the salt part and ignore the hash part. And it still returns a string containing both the salt and the hash. So these strings can be compared
You can clearly understand by:
when user signups for the first time , the process is:
$password = crypt($user_input); // let the salt be automatically generated
if (crypt($user_input, $password) == $password) {
echo "Password verified!";
}
when user tries to login , the process will be :
if(crypt($user_passsword_currentlyin_db, $user_inputted_password) == $user_inputted_password) {
echo "Password verified!";
}
Hope you get the thing :)
EDIT:
The output of crypt consists of:
When you pass this output as "salt" back to crypt, it will extract the right algorithm and salt, and use these for the operation. If there is only an algorithm mentioned, it uses this one and generate random salt. Otherwise it will choose a default algorithm and generate random salt. The hash part in the passed salt parameter is ignored.
So you can simply compare your stored_hash with crypt(password, stored_hash) - if it is equal, it quite likely was the right password.
Here is an pseudocode explanation (in PHP-like syntax) how crypt works:
function crypt($password, $salt)
{
if (substr($salt,0 1) == "_") {
$count = substr($salt, 1, 4);
$real_salt = substr($salt, 5, 4);
return "_" . $count . $real_salt . crypt_ext_des($password, $count, $salt);
}
if(substr($salt, 0, 3) == "$1$") {
list($ignored, $real_salt, $ignored) = explode("$", $salt);
return "$1$" . $real_salt . "$" . crypt_md5($password, $real_salt);
}
if(substr($salt, 0, 4) == "$2a$") {
$cost = substr($salt, 4, 2);
$real_salt = substr($salt, 7, 22);
return "$2a$" . $cost . "$" . $real_salt . crypt_brypt($password, $real_salt, $cost);
}
// ... SHA256 and SHA512 analogons
// no match => STD_DES
$real_salt = substr($salt, 0, 2);
return $real_salt . crypt_std_des($password, $real_salt);
}
Upvotes: 4
Reputation: 13315
$user_input is nothing but your password which is stored in the DATABASE
if(crypt($stored_passsword_in_db, $current_password) == $current_password) {
echo "Password verified!";
}
Hope this helps you....
Upvotes: 0
Reputation: 4075
It is considered good security practice not to store plain text passwords on the server side in case the password file is compromised and user's passwords revealed.
Instead, when the user registers, you should use a one-way hash algorithm on the password before storing it in the database. This way, it is impossible to reproduce the user's password if the file is compromised.
When the user logs in, it is not possible to compare the plaintext password they just entered with that in the database because the password in the database has been hashed.
However, because the same input to a hash function will always produce the same output, line #3 will hash the plaintext input the user just entered and compare it with the hash stored in the database. That way you are comparing hashes with hashes and can establish if the user is authenticated.
A couple notes on security: you should always fail-safe, so your code should read:
if(crypt($user_input, $password) == $password) {
echo "Password verified!";
} else { die("Wrong username/password"); }
Also note that a compromised password file can be reconstructed using a rainbow table.
Upvotes: 1