如何使用password_hash

最近我一直试图通过在互联网上偶然发现的login脚本来实现我自己的安全。 在努力学习如何让自己的脚本为每个用户生成盐之后,我偶然发现了password_hash。

根据我的理解(基于本页面上的阅读: http : //php.net/manual/en/faq.passwords.php ),当您使用password_hash时,salt已经在行中生成。 这是真的?

我的另一个问题是,有2盐是不是聪明? 一个直接在文件中,一个在数据库中? 那样,如果有人在数据库中泄漏了你的盐,那么你还是直接在文件中有一个? 我在这里读到,储存盐不是一个聪明的想法,但它总是让我困惑的人是什么意思。

推荐使用password_hash来存储密码。 不要将它们分开到数据库和文件。

假设我们有以下input:

$password = $_POST['password']; 

为了理解这个概念,我没有validationinput。

你首先做这个哈希密码:

 $hashed_password = password_hash($password, PASSWORD_DEFAULT); 

然后看到输出:

 var_dump($hashed_password); 

正如你可以看到它被哈希。 (我假定你做了这些步骤)。

现在将这个hashed_pa​​ssword存储在你的数据库中,然后让我们说当一个用户要求login它们。你用数据库中的这个散列值检查密码input,通过这样做:

 // Query the database for username and password // ... if(password_verify($password, $hashed_password)) { // If the password inputs matched the hashed password in the database // Do something, you know... log them in. } // Else, Redirect them back to the login page. 

是的,你正确地理解它,函数password_hash()将自己生成一个盐,并将其包含在生成的哈希值中。 将盐存储在数据库中是绝对正确的,即使已知,它也能完成其工作。

 // Hash a new password for storing in the database. // The function automatically generates a cryptographically safe salt. $hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT); // Check if the hash of the entered login password, matches the stored hash. // The salt and the cost factor will be extracted from $existingHashFromDb. $isPasswordCorrect = password_verify($_POST['password'], $existingHashFromDb); 

您提到的第二个盐(存储在文件中的盐)实际上是胡椒粉或服务器端的密钥。 如果你在散列之前添加它(如盐),那么你添加一个胡椒。 有一个更好的方法,你可以先计算哈希,然后用服务器端密钥encryption(双向)哈希。 这使您可以在必要时更改密钥。

与盐相反,这个关键应该保密。 人们经常混淆,试图隐藏盐,但最好让盐做好工作,并用钥匙加上秘密。

对,是真的。 你为什么怀疑function上的PHP常见问题? 🙂

运行password_hash()的结果有四个部分:

  1. 使用的algorithm
  2. 参数
  3. 实际的密码哈希

正如你所看到的,哈希是其中的一部分。

当然,你可以有额外的安全层,但我真的认为这是在一个常规的PHP应用程序的矫枉过正。 默认的bcryptalgorithm是好的,可选的河豚鱼algorithm更好。

千万不要使用md5()来保护你的密码,即使是用盐也是危险的!

使用最新的哈希algorithm来保护您的密码,如下所示。

 <?php // Your original Password $password = '121@121'; //PASSWORD_BCRYPT or PASSWORD_DEFAULT use any in the 2nd parameter /* PASSWORD_BCRYPT always results 60 characters long string. PASSWORD_DEFAULT capacity is beyond 60 characters */ $password_encrypted = password_hash($password, PASSWORD_BCRYPT); ?> 

为了与数据库的encryption密码和用户input的密码相匹配,使用下面的function。

 <?php if (password_verify($password_inputted_by_user, $password_encrypted)) { // Success! echo 'Password Matches'; }else { // Invalid credentials echo 'Password Mismatch'; } ?> 

如果你想使用你自己的盐,使用你自定义生成的函数相同,只是按照下面,但我不推荐这是因为它被发现不推荐在最新版本的PHP。

在使用下面的代码之前阅读这个http://php.net/manual/en/function.password-hash.php

 <?php $options = [ 'salt' => your_custom_function_for_salt(), //write your own code to generate a suitable & secured salt 'cost' => 12 // the default cost is 10 ]; $hash = password_hash($your_password, PASSWORD_DEFAULT, $options); ?> 

希望这些都有帮助!

我已经构build了一个函数,我用它来进行密码validation并创build密码,并将它们存储在mysql数据库中。 它使用随机生成的盐,比使用静态盐更安全。

 function secure_password($user_pwd, $multi) { /* secure_password ( string $user_pwd, boolean/string $multi ) *** Description: This function verifies a password against a (database-) stored password's hash or returns $hash for a given password if $multi is set to either true or false *** Examples: // To check a password against its hash if(secure_password($user_password, $row['user_password'])) { login_function(); } // To create a password-hash $my_password = 'uber_sEcUrE_pass'; $hash = secure_password($my_password, true); echo $hash; */ // Set options for encryption and build unique random hash $crypt_options = ['cost' => 11, 'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)]; $hash = password_hash($user_pwd, PASSWORD_BCRYPT, $crypt_options); // If $multi is not boolean check password and return validation state true/false if($multi!==true && $multi!==false) { if (password_verify($user_pwd, $table_pwd = $multi)) { return true; // valid password } else { return false; // invalid password } // If $multi is boolean return $hash } else return $hash; }