使用PHP的mt_rand()生成哈希盐的安全性?

时间:2012-04-16 23:30:35

标签: php hash salt prng

我正在尝试生成河豚哈希,我想知道它是否足够安全,可以指望mt_rand()为我生成盐?

function blowfish($string, $salt = NULL, $iterations = '08')
{
    if( ! $salt)
    {
        $seed = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        for ($i = 0; $i < 22; $i++)
        {
            $salt .= $seed{mt_rand(0, 63)};
        }
        $salt = '$2a$' . $iterations . '$' . $salt;
    }

    return crypt($string, $salt);
}

上面的字符$ seed是允许的64个字符blowfish-salt alphabet。我打算用它来生成和比较密码。

$password = 'my^$%#password';
$hash = blowfish($password);

if($hash = blowfish($password, $hash))
{
    print "Matches\n";
    print $hash . "\n";
}

修改

我从未意识到这一点,但@zerkms所说的是真的。盐只是为了防止可重复使用的预先计算的攻击,因为盐在他们可以访问哈希的同一点上是已知的。所以目标不是不可逆盐 - 它是随机盐。

那么,这有什么问题吗?

function blowfish($string, $salt = NULL, $iterations = '12')
{
    return crypt($string, $salt ?: "$2a\$$iterations$" . md5(uniqid('', true)));
}

此外,正如标题和上面的代码所述,我实现我自己的哈希算法。

更新2

使用mcrypt扩展名如果加载会导致以下内容,这实际上更快,可能是因为uniqid(u)睡眠或其他事情。

function blowfish($string, $salt = NULL, $iterations = '12')
{
    return crypt($string, $salt ?: "$2a\$$iterations$" . base64_encode(mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)));
}

更新3

base64_encode比md5更快 - 但它中有无效汇流鱼字符,如+。所以现在改为md5。

function blowfish($string, $salt = NULL, $iterations = '12')
{
    return crypt($string, $salt ?: "$2a\$$iterations$" . md5(mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)));
}

2 个答案:

答案 0 :(得分:6)

使用mcrypt创建一个盐。

答案 1 :(得分:4)

使用mt_rand作为盐,足够安全;显然你提供了每个密码使用不同的随机盐。

然而,随着说;几乎任何自行实施的密码散列系统都是不安全的。很少有人精通足以生成和维护安全的密码散列系统。作为参考,我恳请您阅读几个SO线程:

Php/Password best practices

Salt generation and PHP

Do not roll your own

我建议不要自己动手。期。如果可能的话,请考虑使用已建立的PhPass of password hashing库来获取PHP。优势包括实际应用程序测试,高度安全的实施和极易使用。