Crypt()函数的河豚盐长度?

时间:2011-01-13 17:52:36

标签: php passwords cryptography hash blowfish

根据crypt() documentation,盐需要是字母“./0-9A-Za-z”的22位64位数字。

这是他们提供的代码示例:

crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$');

第一个令人困惑的部分是盐有25个字符,而不是22.

问题#1:这是否意味着盐应该更长超过22个字符?

然后我自己测试了这个功能并发现了一些东西。如果我使用20个字符的盐,我会得到这个

// using 20 char salt: 00000000001111111111
crypt('rasmuslerdorf', '$2a$07$00000000001111111111$');
// $2a$07$00000000001111111111$.6Th1f3O1SYpWaEUfdz7ieidkQOkGKh2

所以,当我使用20个字符的盐时,整个盐都在输出中。这很方便,因为我不必将盐存放在一个单独的地方。 (我想使用随机盐)。我将能够从生成的哈希中读回盐。

但是,如果我使用22字符盐作为文档说明,或者更长的盐,最后会切断盐。

// using 22 char salt: 0000000000111111111122
crypt('rasmuslerdorf', '$2a$07$0000000000111111111122$');
// $2a$07$000000000011111111112uRTfyYkWmPPMWDRM/cUAlulrBkhVGlui
// 22nd character of the salt is gone

// using 25 char salt: 0000000000111111111122222
crypt('rasmuslerdorf', '$2a$07$0000000000111111111122222$');
// $2a$07$000000000011111111112uRTfyYkWmPPMWDRM/cUAlulrBkhVGlui
// Same hash was generated as before, 21 chars of the salt are in the hash

问题#2:那么,盐的长度究竟是多少? 20? 22?更长?

问题#3:另外,在检查密码时,是否最好从哈希中读取盐?而不是将盐存储在单独的字段中并从那里读取。 (这似乎是多余的,因为盐似乎包含在哈希中)。

1 个答案:

答案 0 :(得分:8)

Blowfish盐应该是22个字符长(包括尾随$,所以21) - 你可以用var_dump(CRYPT_SALT_LENGTH)仔细检查,我现在无法验证这一点,但我的猜测是较少的字符会返回错误,更多的字符会被截断。

关于你的第三个问题:是的,你应该使用哈希本身的嵌入式salt(和cost)参数来阅读和检查哈希值。