4

我将把它用于用户密码系统,但我首先要确保我做得正确。这是我的测试代码:

函数 generateBlowfishSalt() {
    $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./';
    $numChars = strlen($chars);
    $盐='';

    for($i = 0; $i < 22; ++$i) {
        $salt .= $chars[mt_rand(0, $numChars - 1)];
    }

    返回$盐;
}

$password = 'foo';
$salt = generateBlowfishSalt();
$hash1 = crypt($password, '$2a$12$' . $salt);
$hash2 = crypt($password, $hash1);
$比较 = ($hash1 == $hash2);

printf('密码: %s</br>', $password);
printf('salt: %s</br>', $salt);
printf('hash1: %s</br>', $hash1);
printf('hash2: %s</br>', $hash2);
printf('比较:' . $compare);

这是一个示例输出:

密码:foo
盐:MYVJ32OqLcMGBar3pUa.0S
hash1: $2a$12$MYVJ32OqLcMGBar3pUa.0OTRwv6UX0bcxnSmheKOcqjvqvCrM/p2q
hash2: $2a$12$MYVJ32OqLcMGBar3pUa.0OTRwv6UX0bcxnSmheKOcqjvqvCrM/p2q
比较:1

我的主要问题是:

  1. 我是否正确生成了 22 个字符的盐?我见过base64_encode()的一些实现用于生成盐。我需要这样做吗?

  2. 将整个$hash1值存储在数据库中并且不存储单独的盐值是否正确,因为$hash1其中会有盐,这就是我验证密码所需的全部内容?

  3. 在 PHPcrypt()文档页面上,该CRYPT_BLOWFISH示例的结尾$是 salt 参数(它是:)'$2a$07$usesomesillystringforsalt$'。但在所有的例子中,我看到没有人使用尾随$. 它是可选的吗?

谢谢

4

1 回答 1

0

你做的盐是正确的。只是必须是随机的。有许多不同的方法可以随机生成这个。除了日期时间等之外,有些人还使用它。此外,更长的盐并不意味着什么,因为无论如何它都会被切断。它需要一定的长度,至少就 crypt() 而言。所以如果一点额外的填充让你感觉更好,那就去吧。

您假设将盐存储在数据库中。起初我很难理解这一点。加盐的全部目的只是让用大量可能的密码列表彩虹表所需的时间更长。更正,此外,它还有助于 2 个或多个相同的密码,这是必然发生的。如果是这样,由于随机盐,哈希仍然会有所不同。

至于 crypt() 继续测试它,直到它看起来和 PHP 的 php DOC 中的长度相同,但是它看起来是正确的。

于 2012-05-20T02:23:34.410 回答