我在PHP中正确使用CRYPT_BLOWFISH吗?

时间:2012-05-20 02:13:30

标签: php blowfish

我准备将它用于用户密码系统,但我首先想确保我正确地使用它。这是我的测试代码:

function generateBlowfishSalt() {
    $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./';
    $numChars = strlen($chars);
    $salt = '';

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

    return $salt;
}

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

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

以下是示例输出:

password: foo
salt: MYVJ32OqLcMGBar3pUa.0S
hash1: $2a$12$MYVJ32OqLcMGBar3pUa.0OTRwv6UX0bcxnSmheKOcqjvqvCrM/p2q
hash2: $2a$12$MYVJ32OqLcMGBar3pUa.0OTRwv6UX0bcxnSmheKOcqjvqvCrM/p2q
compare: 1

我的主要问题是:

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

  2. 将整个$hash1值存储在数据库中并且不存储单独的salt值是正确的,因为$hash1将包含salt并且这就是验证密码所需的全部内容

  3. 在PHP crypt()文档页面上,CRYPT_BLOWFISH示例的salt参数的尾随$(就是这样:'$2a$07$usesomesillystringforsalt$')。但是在我看过的所有例子中都没有人使用尾随$。是可选的吗?

  4. 由于

1 个答案:

答案 0 :(得分:0)

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

您可以将salt存储在数据库中。起初我很难理解。盐的全部意义只是让彩虹需要更长的时间才能使用大量可能的密码来填写密码。此外,更正它还有助于2个或更多相同的密码,这些密码必然会发生。如果是这样,由于随机盐,散列仍然会有所不同。

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