tags:

views:

147

answers:

1

Here is the example from the PHP manual page for crypt():

<?php
$password = crypt('mypassword'); // let the salt be automatically generated

/* You should pass the entire results of crypt() as the salt for comparing a
   password, to avoid problems when different hashing algorithms are used. (As
   it says above, standard DES-based password hashing uses a 2-character salt,
   but MD5-based hashing uses 12.) */
if (crypt($user_input, $password) == $password) {
   echo "Password verified!";
}
?>

Why does this work? I take it 'mypassword' is the password I want the actual admin to use. So I crypt that first, and set it equal to $password. Obviously, I must need to store that in the DB. But in the next lines it's being used as both the salt and what I'm comparing to, and I don't understand how crypt($user_input, $password) can possibly be equal to $password, if in this latter case I have ideally the right password as $user_input but salted with $password being compared to $password. It would make more sense to me if the last line were

if (crypt($user_input) == $password) {
   echo "Password verified!";
}

What am I not understanding?

+2  A: 

crypt is a one-way function and returns a string that already contains the salt. The output is similar to what is stored in /etc/shadow.

Example from php.net:

<?php
echo 'result: ' . crypt('somepassword');
echo 'result: ' . crypt('somepassword');
echo 'result: ' . crypt('somepassword');
?>

result: $1$K2D8DGwq$b05uO37aMwO4rnDlB9Rsi1
result: $1$aPBvu2y.$213YVEs8/5m.jMCXSScly/
result: $1$dW3Xu2p6$nuCtJe2zzlgBMLxN2oZCx/

When comparing the user input with the crypt result, the function automatically extracts the salt from the string.

AndiDog
i don't understand how that answers my question...
hatorade
It answers your question perfectly. 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 directly.
gnud
That's what I said.
AndiDog
oh, so by giving it $password as a salt, it's extracting only the salt part, and which was the salt used for the original crypt() call, so i don't ever need to store a salt in my DB, just the hashed PW?
hatorade
yeah sorry it didn't make sense to me when i read it but gnud rephrased it enough so that i think i got it
hatorade