According to the crypt() documentation, the salt needs to be 22 base 64 digits from the alphabet "./0-9A-Za-z".
This is the code example they give:
crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$');
The first confusing part is that salt has 25 characters, not 22.
Question #1: Does that mean the salt is supposed to be longer than 22 characters?
Then I tested the function myself and noticed something. If I use a 20 character salt, I get this
// using 20 char salt: 00000000001111111111
crypt('rasmuslerdorf', '$2a$07$00000000001111111111$');
// $2a$07$00000000001111111111$.6Th1f3O1SYpWaEUfdz7ieidkQOkGKh2
So, when I used a 20 character salt, the entire salt is in the output. Which is convenient, because I do not have to store the salt in a separate place then. (I want to use random salts). I would be able to read the salt back out of the generated hash.
However, if I use a 22 character salt as the documentation says, or a longer one, the salt is cut off at the end.
// using 22 char salt: 0000000000111111111122
crypt('rasmuslerdorf', '$2a$07$0000000000111111111122$');
// $2a$07$000000000011111111112uRTfyYkWmPPMWDRM/cUAlulrBkhVGlui
// 22nd character of the salt is gone
// using 25 char salt: 0000000000111111111122222
crypt('rasmuslerdorf', '$2a$07$0000000000111111111122222$');
// $2a$07$000000000011111111112uRTfyYkWmPPMWDRM/cUAlulrBkhVGlui
// Same hash was generated as before, 21 chars of the salt are in the hash
Question #2: So, what exactly is the proper length of a salt? 20? 22? Longer?
Question #3: Also, is it a good idea to read the salt out of the hash when it is time to check passwords? Instead of storing the salt in a separate field and reading it from there. (Which seems redundant since the salt seems to be included in the hash).
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 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.
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.
In short: yes, that value is absolutely safe to store in a database. Save this answer. Show activity on this post. The hash generated by crypt() is specifically intended to be stored.
Blowfish salts should be 22 chars long (including the trailing $, so 21) - you can double check with var_dump(CRYPT_SALT_LENGTH)
, I can't verify this now but my guess is that less chars will return an error and more chars will be truncated.
Regarding your third question: yes, you should read and check the hash using the embedded salt (and cost) parameters from the hash itself.
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