问题
In PHP manual states that:
CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", a two digit cost parameter, "$", and 22 digits from the alphabet "./0-9A-Za-z".
I realized that the Length of salt is 22. I wrote following code and noticed in the output length of salt is 21.
$encoded = crypt('pass','$2a$08$QAZXSWEDCVFRTGBNHYUJMK'); // Lenght of Q . . . K is 22
echo $encoded;
Output:
$2a$08$QAZXSWEDCVFRTGBNHYUJM./CR85.t4YytTnmLXsRJMfbYWopbT8Nu
K doesn't exist in the salt: QAZXSWEDCVFRTGBNHYUJM
There is something I don't understand?
回答1:
This is due to how the salt is encoded. The actual salt is 128 bit but the encoded salt in the crypt
format is 22 character · 8 bit/character · 3/4 = 132 bit. So 4 bits of the encoded salt are not actually used.
This also means that there are 16 encoded salts that result in the same hash as the first four bits of their least significant character are identical:
$hashes = array();
$chars = array_merge(array('.','/'), range('A','Z'), range('a','z'), range('0','9'));
foreach ($chars as $char) {
$salt = 'QAZXSWEDCVFRTGBNHYUJM'.$char;
$hashes[$salt] = crypt('pass','$2a$08$'.$salt);
}
var_dump($hashes);
Here are the encoded salts that result in the same hash:
QAZXSWEDCVFRTGBNHYUJM.
QAZXSWEDCVFRTGBNHYUJM/
QAZXSWEDCVFRTGBNHYUJMA
QAZXSWEDCVFRTGBNHYUJMB
QAZXSWEDCVFRTGBNHYUJMC
QAZXSWEDCVFRTGBNHYUJMD
QAZXSWEDCVFRTGBNHYUJME
QAZXSWEDCVFRTGBNHYUJMF
QAZXSWEDCVFRTGBNHYUJMG
QAZXSWEDCVFRTGBNHYUJMH
QAZXSWEDCVFRTGBNHYUJMI
QAZXSWEDCVFRTGBNHYUJMJ
QAZXSWEDCVFRTGBNHYUJMK
QAZXSWEDCVFRTGBNHYUJML
QAZXSWEDCVFRTGBNHYUJMM
QAZXSWEDCVFRTGBNHYUJMN
crypt
probably simply uses the first that encodes the internally used 128 bit salt, which is QAZXSWEDCVFRTGBNHYUJM.
.
来源:https://stackoverflow.com/questions/33673318/how-to-retrieve-the-correct-salt-from-phps-password-hash