Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

php

hash

salt

prng

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)));
}
like image 657
Xeoncross Avatar asked Apr 16 '12 23:04

Xeoncross


2 Answers

Use mcrypt to create a salt.

like image 86
Jack Avatar answered Nov 20 '22 03:11

Jack


Using mt_rand for your salt, is secure enough; provided obviously that you utilize a per password different random salt.

However, with that said; nearly any self-implemented password hashing system is insecure. Few individuals are well versed enough to generate and maintain a secure password hashing system. For reference I implore you to read over a few SO threads:

Php/Password best practices

Salt generation and PHP

Do not roll your own

I suggest DO NOT ROLL YOUR OWN. Period. Please look into using the established library of PhPass of password hashing for PHP if possible. Benefits include real-world application testing, highly secure implementation, and extreme ease of use.

like image 30
PenguinCoder Avatar answered Nov 20 '22 01:11

PenguinCoder