Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are PHP's password_hash and password_verify functions enough?

I'm building a site that has users on them, and as with most sites housing some user-type system, they sign in with their e-mails and passwords. I'm using PHP for the back-end portion of my site.

After reading up some articles and posts on the Internet, I learned of the PHP functions password_hash() and password_verify() and wanted to know if an example procedure such as this one was secure enough?

  1. Register the user, password_hash() their password and store the hash in the database.
  2. When logging in, use password_verify() to verify the password and log them in.
  3. If they want to change their password, get their input and password_hash() the input again.

So the questions I have with this are as follows:

  1. Are password_hash() and password_verify() the only functions I need?
  2. Can I take raw user input and safely hash a password using password_hash() for storage in a database?

Any answers would be greatly be appreciated. Thank you.

like image 706
Gumptastic Avatar asked Aug 15 '15 03:08

Gumptastic


People also ask

What algorithm does password_hash use?

Bcrypt cost Bcrypt is the current default hashing algorithm used by password_hash(). This algorithm takes an option parameter named “cost”. The default cost value is 10.

How password_ verify works?

The password_verify() function is used to match the hash password with the original password. Another function, password_hash() is used to generate the hash value based on the hashing algorithm, cost, and salt value. The password_verify() function contains all hashing information to verify the hash with the password.

Is hash different every time?

Yes, if you hash the same input with the same function, you will always get the same result. This follows from the fact that it is a hash-function.

What is password_hash?

password_hash() creates a new password hash using a strong one-way hashing algorithm. The following algorithms are currently supported: PASSWORD_DEFAULT - Use the bcrypt algorithm (default as of PHP 5.5. 0). Note that this constant is designed to change over time as new and stronger algorithms are added to PHP.


1 Answers

Yes to both questions, with a couple of caveats:

  1. Bcrypt truncates after 72 characters. While this doesn't degrade security in any practical way, it still leaves a bad taste in some peoples' mouths. People typically work around this by passing it through a hash function like so (please read the second caveat!):

    password_hash(hash('sha512', $_POST['password'], true), PASSWORD_DEFAULT);
    
    password_verify(hash('sha512', $_POST['password'], true), $storedHash);
    
  2. Bcrypt breaks on NUL bytes, which means that if the SHA512 hash of your password begins with 00, an attacker cracking the hashes will see it as the bcrypt hash of an empty string.

If you want to accept passwords longer than 72 characters without silent truncation, do what we did in password_lock: base-64 encode the raw hash output during hashing AND verification.

(The authenticated encryption of the password hash that password_lock performs is optional, and only increases security if your database is on separate hardware from the webserver.)

But if you're just accepting user's passwords, bcrypt is fine. Most people's 72 character passwords are unbreakable anyway.

like image 75
Scott Arciszewski Avatar answered Sep 27 '22 22:09

Scott Arciszewski