Is PHP password_hash() + password_verify() safe to

2019-02-11 01:00发布

问题:

So the question is pretty much in the title ^^.

Below is a little php code I did to test performance on my server ( + screenshot of the result ) and also show you how I intend to use very simply password_hash() and password_verify().

I think I will go with PASSWORD_BCRYPT and cost = 11 what do you think ?

<?php
$startpage = microtime(true);
$userPassword = "ILike5InchesIceCubes";
echo "<h2>Password we work on :    " . $userPassword . "</h2></br></br>";


echo "<b>password_hash($userPassword, PASSWORD_BCRYPT) :</br></b>";
$start1 = microtime(true);
$hash = password_hash($userPassword, PASSWORD_BCRYPT);
echo "Hash is : " . $hash . "</br>";
echo "Encryption took : ". (microtime(true) - $start1) . " seconds </br>";
$start2 = microtime(true);
password_verify($userPassword, $hash);
echo "Password verification took : ". (microtime(true) - $start2) ." seconds </br></br>";

echo "<b>password_hash($userPassword, PASSWORD_DEFAULT) :</br></b>";
$start1 = microtime(true);
$hash = password_hash($userPassword, PASSWORD_DEFAULT);
echo "Hash is : " . $hash . "</br>";
echo "Encryption took : ". (microtime(true) - $start1) . " seconds </br>";
$start2 = microtime(true);
password_verify($userPassword, $hash);
echo "Password verification took : ". (microtime(true) - $start2) ." seconds </br></br>";

$cost = 4;
do {

        echo "<b>password_hash($userPassword, PASSWORD_BCRYPT, [\"cost\" =>" . $cost . "])</br></b>";
    $start1 = microtime(true);
    $hash = password_hash($userPassword, PASSWORD_BCRYPT, ["cost" => $cost]);
        echo "Hash is : " . $hash . "</br>";
        echo "Encryption took : ". (microtime(true) - $start1) ." seconds </br>";
        $start2 = microtime(true);
        password_verify($userPassword, $hash);
        echo "Password verification took : ". (microtime(true) - $start2) ." seconds </br></br>";

        $cost++;

} while ($cost <= 16);
$endpage = microtime(true);

echo "The whole page took : ". ($endpage - $startpage) . " seconds </br>";
?>

回答1:

Yes, password_hash() is the way to go. There's a great post over at Security StackExchange with more information here:

Using bcrypt is a good start; that's the recommended choice (or at least one of the recommended choices). The documentation seems to indicate that PHP finally does things properly. Make sure that your PHP version is at least 5.5.0. Don't try to fiddle with salts: by default, the function will generate a random salt when needed, and that's the right way to do it, so just let it do its job.

You should try to alter the "cost" option as well. For bcrypt, the cost is a value ranging from 4 to 31; each increment means that the password hashing is twice as expensive, both for your server and for the attacker. In practice, you want to make that value as high as can be tolerated, given your server power, average load, peak load, and maximum user patience: this will give you the best security that you can hope for.

(Note that I said "the best", not "good".)

If you want to understand the underlying concepts for good password hashing, and why bcrypt is a good choice, start here.

password_hash() has been greatly improved in PHP 5.5+, and this, along with PASSWORD_BCRYPT, should be a good way to go.