盐的长度在CRYPT_BLOWFISH

时间:2013-03-31 07:10:08

标签: php bcrypt

在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;

输出:

  

$ 2A $ 08 $ QAZXSWEDCVFRTGBNHYUJM。/ CR85.t4YytTnmLXsRJMfbYWopbT8Nu

salt 中不存在

K QAZXSWEDCVFRTGBNHYUJM

我有些不明白的事情?

1 个答案:

答案 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.