Code:
echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-characters'] );
Result:
Warning: password_hash(): Provided salt is too short: 21 expecting 22
code:
echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-charactersA'] );
Result:
$2y$10$dHdlbnR5LW9uZS1jaGFyYOVyX13hK9eb4/KXMAkHsAJX..YR7t/32
code:
echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-charactersB'] );
$2y$10$dHdlbnR5LW9uZS1jaGFyYOVyX13hK9eb4/KXMAkHsAJX..YR7t/32
Question:
As you see, by appending A and B to 21 character strings we created two different salts of 22 characters, but, the HASHES are same! That is the 22nd character is ignored? If it is ignored then why does it ask for 22 character salt?
First, please don't provide your own salt. You're not going to do a better job generating it than the library does. And using static salts (like you did in the example) will compromise security. Just let it generate its own salt (incidentally, I believe letting a salt in is the biggest mistake I made in that API).
As far as 21 vs 22 characters, give this answer a read.
Basically, the salt is base64 encoded. This means that every 6 bits of the salt is encoded into 8 bits. So every byte of encoded salt is 6 bits.
21 characters is 126 bits. That means that only part of the 22nd character is used (the first 2 decoded bits). The reason you get the same hash with A
and B
, is that the leading 2 bits are the same for both characters.
In fact, there are only 4 unique hashes for the 22nd byte.
BCrypt expects a salt of a given alphabet: ./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
. As you can see the '-' is not in it and that's why your salt is invalid. A valid salt you could see plaintext in the hash-value.
In most cases it is best to omit the salt parameter. Without this parameter, the function will generate a cryptographically safe salt, from the random source of the operating system.
password_hash("stackoverflow", PASSWORD_DEFAULT);
Nevertheless you are right, when you say that BCrypt does not use the full 22 characters. It seems that BCrypt only uses 126 bits of the salt instead of the 128bits you get with 22 base64 encoded characters. For more information you can have a look at this discussion Why does crypt/blowfish generate the same hash....
来源:https://stackoverflow.com/questions/26295266/php-password-hash-function-salt-length-21-or-22