I was here yesterday and got some really great answers. I took what I got and put together, what I think will be a fairly secure algorithm. I'm having a problem using blowfish with a for loop that generates the salt.
I'm using base64 characters and a for loop to get a random string. I want to take this generated string and insert it into the crypt function as the salt.
Because the documentation about blowfish is so sparse and the PHP docs don't really even mention it, I'm sort of stabbing in the dark here.
The really strange thing is if you run this code the way it is now, it will not fail. Remove either the '$2a$07$' from above the for loop or from the crypt function and it will intermittently return an encrypted string. My understanding of blowfish is that the encrypted string must begin with '$2a$07$' and end in "$' hence the concatenation in the crypt function. I really don't need the beginning string above the for loop and just wanted to get rid of it.
I also would like clarification about the best practice on storing the random salt, either in the database or by storing the output of the crypt function in the database?
Yesterday, there was no real code being thrown around, just discussion. I'd like to put some code together today and have something that is fairly secure in place. If anyone can come up with a better algorithm, I'm always open.
$base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
$salt = '$2a$07$';
for($i=0; $i<60; $i++)
{
$salt .= $base64[rand(0,63)];
}
return crypt('password', '$2a$07$'.$salt.'$');
Definition and Usage. The crypt() function returns a hashed string using DES, Blowfish, or MD5 algorithms. This function behaves different on different operating systems. PHP checks what algorithms are available and what algorithms to use when it is installed. The salt parameter is optional.
In short: yes, that value is absolutely safe to store in a database.
The crypt() function generates an encoded version of each password. The first call to crypt() produces an encoded version of the old password; that encoded password is then compared to the password stored in the user database. The second call to crypt() encodes the new password before it is stored.
What is a salt? A cryptographic salt is data which is applied during the hashing process in order to eliminate the possibility of the output being looked up in a list of pre-calculated pairs of hashes and their input, known as a rainbow table.
It seems that the crypt()
dislikes +
char in the salt, and a lot of other special chars as well (*
, %
etc). If you filter them out it should work on every try (and no need repeating the salt id string).
I know this question is practically ancient history now, but for the benefit of anyone who finds it by searching google, there is a pretty detailed description of how the bcrypt/EksBlowfish salts work in the answer to this question:
Why does crypt/blowfish generate the same hash with two different salts?
The short answer is, as caf said, it uses a base64 alphabet composed of [a-zA-Z0-9./]
, with $
as the null (NOT 0) terminating/padding character. If you use any characters outside of that range, or a $
too early, it will either error out or not interpret the entirety of the salt.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With