I'm learning about PHP's crypt() function and have been running some tests with it. According to this post, I should use a salt that's 22 characters long. I can, however, use a string that's 23 characters long with some limitations. When I use a 22 character long string I always get an outcome of '$2y$xxStringStringStringStri.HashHashHashHashHashHashHashHas'. I know the period is just part of the salt.
It seems that if I use 23 characters instead of just 22, I can successfully generate different hashes, but there is only 4 different outcomes for all 64 characters. The 23rd character "rounds down" to the nearest 1/4th of the 64 character alphabet (e.g. the 23rd character is "W" and rounds down to "O" or any number rounds down to "u")
v---------------v---------------v---------------v---------------
./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890
All four of these crypt functions generate the same salt:
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAq');
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAr');
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAs');
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAt');
But this one is different:
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAu');
So why shouldn't I use the 23rd character when it can successfully generate different outcomes? Is there some kind of glitchy behavior in PHP that should be avoided by not using it?
For clarification on how I'm counting the 23rd character in the salt:
crypt('Test123','$2y$08$ABCDEFGHIJKLMNOPQRSTUV');
// The salt is '$ABCDEFGHIJKLMNOPQRSTUV'
// Which will be treated as '$ABCDEFGHIJKLMNOPQRSTUO'
It has to do with hash collisions. Once you exceed 22 characters your generated hashes are no longer unique depending on the NAMESPACE
of the algorithm. To be said another way, more than 22 characters doesn't result in any increased security and can actually decrease your level of security.
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