在PHP手册中说明:
CRYPT_BLOWFISH - 河豚用盐调和如下:“$ 2a $”,a 两位数的成本参数,“$”和字母表中的22位数字 “./0-9A-Za-z”。
我意识到盐的长度是22 。我写了下面的代码,注意到 salt 的输出长度是 21 。
$encoded = crypt('pass','$2a$08$QAZXSWEDCVFRTGBNHYUJMK'); // Lenght of Q . . . K is 22
echo $encoded;
输出:
salt 中不存在$ 2A $ 08 $ QAZXSWEDCVFRTGBNHYUJM。/ CR85.t4YytTnmLXsRJMfbYWopbT8Nu
K : QAZXSWEDCVFRTGBNHYUJM
我有些不明白的事情?
答案 0 :(得分:4)
这是由于盐的编码方式。实际的盐是128位,但crypt
格式的编码盐是22个字符·8位/字符·3/4 = 132位。因此实际上没有使用4位编码盐。
这也意味着有16个编码的盐导致相同的哈希值,因为它们的最低有效字符的前四位是相同的:
$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);
以下是导致相同散列的编码盐:
QAZXSWEDCVFRTGBNHYUJM.
QAZXSWEDCVFRTGBNHYUJM/
QAZXSWEDCVFRTGBNHYUJMA
QAZXSWEDCVFRTGBNHYUJMB
QAZXSWEDCVFRTGBNHYUJMC
QAZXSWEDCVFRTGBNHYUJMD
QAZXSWEDCVFRTGBNHYUJME
QAZXSWEDCVFRTGBNHYUJMF
QAZXSWEDCVFRTGBNHYUJMG
QAZXSWEDCVFRTGBNHYUJMH
QAZXSWEDCVFRTGBNHYUJMI
QAZXSWEDCVFRTGBNHYUJMJ
QAZXSWEDCVFRTGBNHYUJMK
QAZXSWEDCVFRTGBNHYUJML
QAZXSWEDCVFRTGBNHYUJMM
QAZXSWEDCVFRTGBNHYUJMN
crypt
可能只是使用第一个对内部使用的128位盐进行编码,即QAZXSWEDCVFRTGBNHYUJM.
。