使用bcrypt:我应该分配多少字节?

时间:2012-08-05 04:36:09

标签: php sql hash bcrypt

我将密码存储在SQL数据库中,使用PHP并计划使用bcrypt。

我正在做一些研究,以找出我应该使用什么类型和大小来存储我的数据库中的哈希和盐。

根据this question的答案,似乎bcrypt有时输出不同大小的哈希值,可能与CHAR(76)BINARY(60)一样大。但我不明白何时以及为何。

该问题提供link,表示使用$2$方案产生59个字节,$2a$产生60个字节。但是今天的php crypt的文档建议使用$2y$而不是$2a$,由于某些原因,由于高位攻击或其他原因。无论如何,我想按照建议使用$2y$,但没有迹象表明它将输出的大小。

数据库中我的字段大小应该是多少?

此外,CHARBINARY在此类应用中是否存在实际差异?

2 个答案:

答案 0 :(得分:1)

  1. 哈希:CHAR(60)
  2. 盐:CHAR(22)
  3. 这可以通过实验找到:

    <?php
        $salt1 = "FotZoGZruCl8ugk0Tvl4g";
        $salt2 = "FotZoGZruCl8ugk0Tvl4g9";
        $salt3 = "FotZoGZruCl8ugk0Tvl4g9a";
    
        print 'Salt 1 (stlen = ' . strlen($salt1) . '): ' . $salt1 . '<br />';
        print 'Salt 2 (stlen = ' . strlen($salt2) . '): ' . $salt2 . '<br />';
        print 'Salt 3 (stlen = ' . strlen($salt3) . '): ' . $salt3 . '<br />';
    
        $hash1 = crypt('password1', '$2y$07$' . $salt1);
        $hash2 = crypt('password1', '$2y$07$' . $salt2);
        $hash3 = crypt('password1', '$2y$07$' . $salt3);
    
        print 'Hash 1 (strlen = ' . strlen($hash1) . '): ' . $hash1 . '<br />';
        print 'Hash 2 (strlen = ' . strlen($hash2) . '): ' . $hash2 . '<br />';
        print 'Hash 3 (strlen = ' . strlen($hash3) . '): ' . $hash3 . '<br />';
    ?>
    

    输出将是:

    Salt 1 (stlen = 21): FotZoGZruCl8ugk0Tvl4g
    Salt 2 (stlen = 22): FotZoGZruCl8ugk0Tvl4g9
    Salt 3 (stlen = 23): FotZoGZruCl8ugk0Tvl4g9a
    Hash 1 (strlen = 60): $2y$07$FotZoGZruCl8ugk0Tvl4g.pXg.UBUUwuj14Ur1d.z/tMLqGPxQLBW
    Hash 2 (strlen = 60): $2y$07$FotZoGZruCl8ugk0Tvl4guNd47GUslNQPXiel70rI0yvffP7iPSHe
    Hash 3 (strlen = 60): $2y$07$FotZoGZruCl8ugk0Tvl4guNd47GUslNQPXiel70rI0yvffP7iPSHe
    

    你会注意到,如果你添加超过22个字符的盐,哈希将保持不变。也就是说,在执行哈希之前,crypt会将盐截断为22个字符。

    仅供参考,随机盐生成:

    $salt = substr(strtr(base64_encode(mcrypt_create_iv(17, MCRYPT_DEV_URANDOM)), "=+", "./"), 0, 22);
    

    编辑: 此外,salt / hash的格式是base 64.即使用a-z,A-Z,0-9,'。'和'/'作为数字,每个数字代表一个从0到63的值...所以在数据库中使用CHAR对于BINARY是好的,因为你可以用{{代表所有这些数字1}}。

答案 1 :(得分:0)

它的大小相同 - 60个字符。 ($2$$2a$之间的唯一区别是前者是少一个字符。实际的散列部分大小相同。)