28

I'm making a login system, and I want to hash the passwords to make them more secure, but it returns a different hash every time, and can't even be verified using password_verify(), here is my code:

$password = password_hash($password4, PASSWORD_DEFAULT);

and here is my code for verifying:

if(password_verify($password4, $dbpassword))
Machavity
  • 30,841
  • 27
  • 92
  • 100
ItzBenteThePig
  • 696
  • 1
  • 9
  • 19
  • 2
    You shouldn't be using [`password_hash()`](http://jayblanchard.net/proper_password_hashing_with_PHP.html) that way. – Jay Blanchard Oct 13 '15 at 17:20
  • @JohnConde I got rid of the md5 function, I can't see why it would fix it though, which I am right about, the only reason I have it there is to make it more secure. – ItzBenteThePig Oct 13 '15 at 17:20
  • @JayBlanchard How should I use it then? – ItzBenteThePig Oct 13 '15 at 17:21
  • @PeeHaa It would take longer to crack it if it is hashed with different hashes multiple times – ItzBenteThePig Oct 13 '15 at 17:22
  • 4
    That assertion is incorrect @ItzBenteThePig - additional hashing makes for problems, rather than solutions. Think about what you're trying to protect. `password_hash()`, used correctly, provides random salts and long hashes that would take hundreds of years to crack. – Jay Blanchard Oct 13 '15 at 17:23
  • @JayBlanchard Oh, I didn't notice it. – ItzBenteThePig Oct 13 '15 at 17:23
  • @ItzBenteThePig did you read the documentation of `password_verify`? Namely this part: *Note that password_hash() returns the algorithm, cost and salt as part of the returned hash. Therefore, all information that's needed to verify the hash is included in it. This allows the verify function to verify the hash without needing separate storage for the salt or algorithm information.* That should clear up why it isn't working. – Script47 Oct 13 '15 at 17:23
  • @Script47 Yes I did, but that doesn't help me, maybe I'm just stupid, or maybe I'm missing something. – ItzBenteThePig Oct 13 '15 at 17:26
  • 1
    One other note: [Don't limit passwords.](https://xkcd.com/936/) [Passphrases are the key to higher security.](http://jayblanchard.net/security_fail_passwords.html) – Jay Blanchard Oct 13 '15 at 17:29
  • 1
    @JayBlanchard For me those links just looks as a guide to creating a secure password, not hashing them. – ItzBenteThePig Oct 13 '15 at 17:34
  • 1
    I rolled back to your original question as the *stealth* edit makes it seem that your function is not working properly. The additional function call is what was getting you into a bind, editing that out changes the nature of the question. – Jay Blanchard Oct 13 '15 at 17:34
  • Hashing is taken care of by the `password_hash()` function. What more do you need to know @ItzBenteThePig? The docs provide for different hashing methodologies if you'd like to use them. – Jay Blanchard Oct 13 '15 at 17:35
  • 1
    @JayBlanchard If I'm still having the same problem, I assume that was not what was causing it, and therefore I don't think it's changing the nature of the question, it's just changing the look of the question – ItzBenteThePig Oct 13 '15 at 17:36
  • Ah - and I just rolled yours back because it left out the original code @PeeHaa! LOL. We need to combine the original code with the updates your requested. – Jay Blanchard Oct 13 '15 at 17:37
  • @ItzBenteThePig if you have followed, to the letter, how to hash and then verify the password then there is A.) an error we don't know about or 2.) some other code which might be interfering. – Jay Blanchard Oct 13 '15 at 17:41

1 Answers1

53

So let's take it one part at a time

but it returns a different hash every time

That's the idea. password_hash is designed to generate a random salt every time. This means you have to break each hash individually instead of guessing one salt used for everything and having a huge leg up.

There's no need to MD5 or do any other hashing. If you want to raise the security of password_hash you pass a higher cost (default cost is 10)

$password = password_hash($password4, PASSWORD_DEFAULT, ['cost' => 15]);

As to verify

if(password_verify($password4, $dbpassword))

So $password4 should be your unhashed password and $dbpassword should be the hash you've stored in your database

Machavity
  • 30,841
  • 27
  • 92
  • 100