Search code examples
phphashsalt-cryptographyprng

Security of generating hash salts using PHP's mt_rand()?


I'm trying to generate blowfish hashes and I was wondering if it's safe enough to count on mt_rand() to generate my salts for me?

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);
}

The character $seed above is the allowed 64-character blowfish-salt alphabet. I plan on using this to generate and compare passwords.

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

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

Edit

I never realized this, but what @zerkms says is true. Salts are only to prevent reusable precomputed attacks since the salt is known at the same point that they have access to the hash. So the goal isn't a non-reversible salt - it's a random salt.

So, anything wrong with this?

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

Also, as noted in the title and above code, I'm not implementing my own hashing algorithm.

Update 2

Using the mcrypt extension if loaded leads to the following, which is actually faster probably because uniqid (u)sleeps or something.

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

Update 3

base64_encode is faster than md5 - but it has invalid blowfish characters in it like +. So changed to md5 now.

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

Solution

  • Use mcrypt to create a salt.