简体   繁体   中英

Trying to hash a password, but every time it just hashes to *0

I'm learning how to hash passwords using PHP for obvious security reasons. I have the two following functions for setting and checking hashes:

function password_encrypt($password)
{
    $hash_format = "$2y$10$"; //blowfish
    $salt_length = 22;
    $unique_random_string = md5(uniqid(mt_rand(), true));
    $base64_string = base64_encode($unique_random_string);
    $modified_base_64_string = str_replace('+', '.', $base64_string);
    $salt = substr($modified_base64_string, 0, $length);
    $format_and_salt = $hash_format . $salt;
    $hash = crypt($password, $format_and_salt);
    echo $hash;
    return $hash;
}

function password_check($password, $existing_hash)
{
    $hash = crypt($password, $existing_hash);
    if($hash === $existing_hash)
    {
        return true;
    }
    else
    {
        return false;
    }
}

My issue is that every time I hash a password and send it off to the database it just gets stored as *0. I don't know where the *0 is coming from. Is there something wrong with what I'm doing?

Basically when I use it I just grab the entered password from $_POST and encrypt it using password_encrypt(). But it seems like it always comes out the other side as *0.

Short and Correct Answer

Don't roll your own cryptography, use an implementation that has already been vetted by security experts. For PHP 5.5 and above, this means password_hash() and password_verify() . For earlier versions of PHP, you can use password_compat (if your PHP version is older than 5.4, shame on you for running unsupported versions of PHP).

The Crypto Self-Education Answer

If you're dead set on writing your own cryptography code (for the learning experience, etc.), you must promise to never deploy your unproven implementation and make anything depend on it for security. Otherwise, just use password_hash() and password_verify() and stop reading right now.


There are a lot of problems with your code. Let's go down the line systematically, starting with password_encrypt() . (By the way, you aren't encrypting a password, you're hashing it.)

$unique_random_string = md5(uniqid(mt_rand(), true));

Yeah, NO . This is not a cryptographically secure way to generate a salt for a bcrypt hash. You should take a look at how password_compat implements this feature. Alternatively, see how random_compat generates random bytes for cryptographic purposes. (Also, please tell whomever advised you to use that one-liner to generate random strings that they are playing with fire.)

$unique_random_string = random_bytes(17);

Moving on...

$modified_base_64_string = str_replace('+', '.', $base64_string);
$salt = substr($modified_base64_string, 0, $length);

You forgot an underscore in the second variable name. Also, there is no variable named $length . These lines, corrected, look like so:

$modified_base_64_string = str_replace('+', '.', $base64_string);
$salt = substr($modified_base_64_string, 0, $salt_length);

Next,

$hash = crypt($password, $format_and_salt);
echo $hash;
return $hash;

Please don't leave your echo statements in your example code. Also, you should check for errors and throw an exception so your application doesn't chug happily along if bcrypt hashing fails.

$hash = crypt($password, $format_and_salt);
if ($hash === '*0') {
    throw new Exception('Password hashing unsuccessful.');
}
return $hash;

Whew, almost done. Let's look at your password_check() function now:

if($hash === $existing_hash)
{
    return true;
}
else
{
    return false;
}

Don't compare cryptographic outputs (password hashes, MACs, etc.) using == or === , or else you invite timing attacks into your application. Use hash_equals() for PHP 5.6, or a hash_equals() polyfill for earlier versions of PHP .

return hash_equals($hash, $existing_hash);

I hope this was an educational experience. Cryptography is hard, don't reinvent the wheel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM