Php CRYPT_河豚体内盐的长度

Php CRYPT_河豚体内盐的长度,php,bcrypt,Php,Bcrypt,PHP手册中规定: CRYPT_河豚-河豚用盐散列如下:“$2a$”,a 两位成本参数“$”和字母表中的22位 “/0-9A-Za-z” 我意识到盐的长度是22。我编写了以下代码,并注意到输出中salt的长度是21 输出: $2a$08$QAZXSWEDCVRTGBNHYUJM./CR85.t4YytTnmLXsRJMfbYWopbT8Nu 盐中不存在钾:QAZXSWEDCVFRTGBNHYUJM 有件事我不明白?这是因为盐是如何编码的。实际salt为128位,但crypt格式中的编码salt为

PHP手册中规定:

CRYPT_河豚-河豚用盐散列如下:“$2a$”,a 两位成本参数“$”和字母表中的22位 “/0-9A-Za-z”

我意识到盐的长度是22。我编写了以下代码,并注意到输出中salt的长度是21

输出:

$2a$08$QAZXSWEDCVRTGBNHYUJM./CR85.t4YytTnmLXsRJMfbYWopbT8Nu

盐中不存在钾:QAZXSWEDCVFRTGBNHYUJM


有件事我不明白?

这是因为盐是如何编码的。实际salt为128位,但
crypt
格式中的编码salt为22个字符·8位/字符·3/4=132位。所以4位编码的salt实际上并没有被使用

这也意味着有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位salt进行编码的salt,即
QAZXSWEDCVFRTGBNHYUJM。

我不确定你在问什么。为什么K必须在salt中?因为
K
salt
字符串中,这是不够的?不理解这一点:
3/4=132位这意味着什么?@msoa编码三个字节的输入和四个字节的编码输出。在相反的过程中,四个字节的编码输入被解码为三个字节的输出。这就是为什么22字节的Base64编码数据会产生132位的解码数据。更简单的是:每个Base64编码字符需要6位
22*6=132
还有一个问题:在Base64索引表中没有
字符,是否对
+
/
或任何字符进行内部转换?或者当Base64解码发生这种情况时?@msoa bcrypt不使用,但使用一个稍有不同的顺序:它的顺序是
a
Z
a
Z,
0
9
,与
a
相对,
0
9
+
/
QAZXSWEDCVFRTGBNHYUJM.
QAZXSWEDCVFRTGBNHYUJM/
QAZXSWEDCVFRTGBNHYUJMA
QAZXSWEDCVFRTGBNHYUJMB
QAZXSWEDCVFRTGBNHYUJMC
QAZXSWEDCVFRTGBNHYUJMD
QAZXSWEDCVFRTGBNHYUJME
QAZXSWEDCVFRTGBNHYUJMF
QAZXSWEDCVFRTGBNHYUJMG
QAZXSWEDCVFRTGBNHYUJMH
QAZXSWEDCVFRTGBNHYUJMI
QAZXSWEDCVFRTGBNHYUJMJ
QAZXSWEDCVFRTGBNHYUJMK
QAZXSWEDCVFRTGBNHYUJML
QAZXSWEDCVFRTGBNHYUJMM
QAZXSWEDCVFRTGBNHYUJMN