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

Xeo*_*oss 6 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);
}
Run Code Online (Sandbox Code Playgroud)

上面的字符$ seed是允许的64个字符的河豚盐字母表.我打算用它来生成和比较密码.

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

if($hash = blowfish($password, $hash))
{
    print "Matches\n";
    print $hash . "\n";
}
Run Code Online (Sandbox Code Playgroud)

编辑

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

那么,这有什么不对吗?

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

另外,如标题和上面的代码中所述,我没有实现自己的哈希算法.

更新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)));
}
Run Code Online (Sandbox Code Playgroud)

更新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)));
}
Run Code Online (Sandbox Code Playgroud)

Jac*_*ack 6

使用mcrypt创建一个salt.