4

在 PHP 手册中指出:

CRYPT_BLOWFISH - 使用盐的 Blowfish 散列如下:“$2a$”,两位数的成本参数,“$”和字母表中的 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

中不存在KQAZXSWEDCVFRTGBNHYUJM

有什么我不明白的吗?

4

1 回答 1

5

这是由于盐的编码方式。实际的盐是 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..

于 2013-03-31T08:00:12.677 回答