I am reading up on PHP's crypt() function. I have a few questions on it -
What is the significance of the trailing '$' sign at the end of the salt string that I see in most examples. The manual doesn't specifically say anything about ending the salt string with it.
Is there anyway I can extract only the salt portion from the hash? I know that I probably don't need to, since the crypt() function will internally do it when doing a comparison. But just for the heck of it. Just for me to see the salt. For egs consider this code -
$pass = 'secret'; $salt = '$2y$07$usesomesillystringforsalt$'; echo crypt($pass, $salt);
The output of this is $2y$07$usesomesillystringforex.u2VJUMLRWaJNuw0Hu2FvCEimdeYVO
and I am unsure about the boundary between the salt and the hash. Is the 'e' in the 'forex' sub string part of the salt or the hash? It would be much easier if I could just extract the salt part of it.
Also the crypt() manual says
... Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z"....
As per this I expect 22 characters after the $ sign following the cost parameter. But consider this code -
$pass = 'secret'; $salt = '$2y$07$somesillystring$'; echo crypt($pass, $salt);
The output of this is $2y$07$somesillystring$$$$$$.O6JLPmGlDvy4BicGmkuBD.DN8OYiIoG
. My question is why is it padded only up to 21 characters following the $ sign after the cost parameter. I was expecting it to be padded up to 22 characters.
Some crypt() algorithms separate the salt from the crypt with a dollar sign. Blowfish doesn't.
PHP provides no facility for just extracting the salt. You would need an associative array of algorithms and salt positions/lengths.
I'm not sure why the 21 vs 22 character difference. Could it be an error in the PHP manual? Try running "man crypt" or go to http://linux.die.net/man/3/crypt .
I vagely remember reading somewhere that only the left 4 bits/nibble of the 22th character is used. But after the running the following snippet I can't see a relation between the binary representation of the 22th character before and after hashing. But the 22th character does have an effect on the outcome.
$pass = 'secret';
$salt = '$2y$07$usesomesillystringforsalt$';
$hash = crypt($pass, $salt);
var_dump(
$hash,
str_split($hash) // the 22th salt character 'e' is on index 28
);
function meow($char) {
$hash = crypt('secret', '$2y$04$usesomesillystringfor' . $char);
$substr = substr($hash, 28, 1);
var_dump(
$hash,
$char,
decbin(ord($char)),
$substr,
decbin(ord($substr)),
'------------------------------'
);
}
$alphabet = str_split('abcdefghijklmnopqrstuvwxyz');
foreach($alphabet as $char) {
meow($char);
}
See for yourself: http://3v4l.org/qQmho