Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
434 views
in Technique[技术] by (71.8m points)

php - Password does not match after being encrypted using crypt() and password_hash() function

I modified my old post. I tried the crypt() function and now trying to work with password_hash() and password_verify() to verify the encrypted password coming from database but on each call, password_hash() function retuns a different encrypted string and password_verify() cannot match it.

This is how I am doing this.

 //please ignore the syntax error if any

$data = '11';
$dbpass = password_hash($data, PASSWORD_BCRYPT);
echo $dbpass;  // displays the random strings on each page refresh.

Once password is saved into database does not get match during the login process. Below is my actual function.

   private function process_data($password){
    $password = __STR.$password.__STR;
    return  password_hash($password, PASSWORD_BCRYPT);

  }
  private function processed($login_password, $dbpassword){
    $login_password = __STR.$login_password.__STR;
    return password_verify($login_password, $dbpassword);
  }

On each function call for creating a hashed string for password, the function returns the different string next time.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok, Let's go through this one by one.

First, it's hashing, not encryption. Encryption is two-way, hashing is one way. We want to hash. We never want to encrypt. Yes, terminology matters. Please use the correct terminology.

Next, each call to password_hash is supposed to return a different hash. That's because it's generating a strong random salt. This is how it was designed, and how you really should be using it.

Further, DO NOT do the "pepper" thing of adding __STR before and after the password. You're doing nothing but potentially weakening the users password (which is not good). If you want more information around why that's a bad idea: Read This Answer.

Continuing, I would highly recommend that you do not use crypt directly. It is actually surprisingly easy to screw up and generate extremely weak hashes. This is why the password_* api was designed. crypt is a low level library, you want to use a high level library in your code. For more information on ways to screw up bcrypt, check out my blog: Seven Ways To Screw Up Bcrypt.

The Password API was designed to be a simple, one-stop shop. If it's not working for you check the following things:

  1. Are you using PHP >= 5.5.0? Or are you using PHP >= 5.3.7 with password_compat?

    1. Is your database column wide enough?

      It needs to be at least 60 characters long.

    2. Are you checking that the result of the function is a string, and not bool(false)?

      If there is an internal error, it will return a non-string from password_hash.

    3. Are you getting any errors?

      Have you turned on error_reporting to its maximum setting (I recommend -1 to catch everything) and checked that the code isn't throwing any errors?

    4. Are you sure you are using it correctly?

      function saveUser($username, $password) {
          $hash = password_hash($password, PASSWORD_BCRYPT);
          // save $username and $hash to db
      }
      function login($username, $password) {
          // fetch $hash from db
          return password_verify($password, $hash);
      }
      

      Note that each one should be called only once.

  2. Are you using PHP < 5.3.7 with password_compat? If so, this is your problem. You are using the compatability library on an unsupported version of PHP. You may get it to work (certain RedHat distributions have backported the necessary fixes), but you are using an unsupported version. Please upgrade to a reasonable release.

If all else fails, please try running this code and reporting back the output:

$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
$test = crypt("password", $hash);
$pass = $test == $hash;

echo "Test for functionality of compat library: " . ($pass ? "Pass" : "Fail");
echo "
";

If that returns Fail, you are running an unsupported version of PHP and should upgrade. If it returns pass, than the error is somewhere in your logic (the library is functioning fine).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...