5

I'm try to hash user password with using password_hash() PHP function.But,it function is work hashing,not constant.

<?php 
    echo password_hash('a',PASSWORD_BCRYPT,array(
            'cost' => 12
         ));
?>

Result for 4th testing time

1. $2y$12$SRmipqM7AsYkx3Xc8QGHNex69rGXeVyWGTYrh9T8sh1cP3UrdjfQi
2. $2y$12$zx.GUgtcake3wMfl3/YXXeG1.8mmHKyRruL3nWj8OmA.RbEYqeW6u
3. $2y$12$XQtmFplcehkgWLbGrOUsNOlXDU/NGrwZlt3HM88hLbUHXhjXNF4km
4. $2y$12$q9/OSZdDJw7af4Hw4MGlHeY7UMtWr9/Cj0nj/N6PaoilNoUBePt7O
lwinkyawmyat
  • 1,221
  • 1
  • 16
  • 34
  • What do you expect? That it would be constant ? – Rizier123 Feb 20 '15 at 10:07
  • 5
    Everytime you use `password_hash()` without the **salt** it will generate a random salt, which means your password would not be constant. as `password_hash()` generates the hash and the hash is basicly salt + hash `password_verify()` method expects the password and the hashed password the password [param 1] will be hashed using the salt from the hashed password, if it equals it returns true, else it fails :-) – Mike M. Feb 20 '15 at 10:27

3 Answers3

10

As some suggested to use MD5, Do not use it for password hashing.

Well now to answer your question how to check a password matches

Password_Hash() is to generate a password hash, which will create a random salt with it, this hash will be used upon hashing. your end result would be: salt+hash, however you can give it a salt with this method in it's options but let's keep it that it does it by itselves.

Password_Verify() uses a parameter for the password and one for the hashed password. as I said earlier the hashed password is salt+hash which makes sense that Password_Verify() only need these and not an additional called salt

So what happens with Password_Verify() is that it takes out the salt and use Password_Hash() with that salt. then check if the received hash equals the given hash. if it matched then it's true, else it's false.

Password_Hash() Doc

Password_Verify() Doc


Update 18-04-2018 (d-m-Y)

WARNING

The salt option has been deprecated as of PHP 7.0.0.

It is now preferred to simply use the salt that is generated by default.

More information about Salting - SO Answer below by Veve

Why not to use MD5 for Password Hashing - PHP FaQ Answer

Why not to use MD5 for Password Hashing - SO Answer by: Silverlightfox

Community
  • 1
  • 1
Mike M.
  • 361
  • 2
  • 14
  • No problem and remember, if it helped don't forget to accept the answer :-) I would also definitaly say: Just use the methods given. the salt generated is perfectly fine, use the `password_hash()` with `password_verify()` – Mike M. Feb 20 '15 at 10:43
  • I really understand `password_hash()` and `password_verify()` . Thank you @MikeM . I'm too late for accept for your answer. – lwinkyawmyat Feb 25 '16 at 08:40
2

If you want to use password_hash() and get constants hashes (not sure of the plural...), add a salt when using it. (but don't, see the caution below)

As explained in the doc, if you don't, the salt will be randomly generated each time you use the function, and as a result the generated hash won't be constant.

<?php 
    echo password_hash('a',PASSWORD_BCRYPT,array(
            'salt' => $salt_defined_for_the_user,
            'cost' => 12,
         ));
?>

About the salt you should use, here is a good explaination of wmfrancia extracted from here:

SALTING

Passwords should always be salted before hashed. Salting adds a random string to the password so similar passwords don't appear the same in the DB. However if the salt is not unique to each user (ie: you use a hard coded salt) than you pretty much have made your salt worthless. Because once an attacker figures out one password salt he has the salt for all of them.

When you create a salt make sure it is unique to the password it is salting, then store both the completed hash and salt in your DB. What this will do is make it so that an attacker will have to individually crack each salt and hash before they can gain access. This means a lot more work and time for the attacker.


Caution: you should'nt try to get constants hashes with your own salt

I'm simply responding here to your willing to have constant hashes, but as said by halfer and martinstoeckli in the comments, and also noted in the official doc,

Caution It is strongly recommended that you do not generate your own salt for this function. It will create a secure salt automatically for you if you do not specify one.

.

You really should not create your own salt, the function tries its best to create a safe and random one. When you store a user specific salt as your example shows, you do the same as password_hash() does anyway. It includes the salt in the hash-value so the function password_verify() can pick it up from there

Mike M. has a detailed description for the use of password_verify() instead in his answer.

Community
  • 1
  • 1
Veve
  • 6,643
  • 5
  • 39
  • 58
  • **$salt_defined _for_the_user** is just need minimum 22 character. :P :) – lwinkyawmyat Feb 20 '15 at 10:45
  • 1
    Unless you know what you are doing, I suggest using the default salt capabilities of this function. – halfer Feb 20 '15 at 10:54
  • You really should _not_ create your own salt, the function tries its best to create a safe and random one. When you store a user specific salt as your example shows, you do the same as `password_hash()` does anyway. It includes the salt in the hash-value so the function `password_verify()` can pick it up from there. – martinstoeckli Feb 20 '15 at 11:39
  • I don't say he has to create a salt, I'm simply answering his question about getting constant hashes. I'll add your warning to my answer. – Veve Feb 20 '15 at 13:07
  • Veve check my answer I explained it in details, there is also a warning under the first examples under Note starting with **CAUTION** in the Password_Hash() doc – Mike M. Feb 20 '15 at 16:16
  • Again, totally agree with you, hence the added notice, that I'll make more proiminent with link to your answer :) I can quote it if you want. – Veve Feb 20 '15 at 18:06
0

I think you are confused by the older methods that produce the same hash no matter how many times you try.

Eg MD5 () would five you the same hash for the same password all the time..

Password_hash gives you different string all the time as it contains a different salt each tim you run it.

When you retrieve the hash password from the database (eg based on the email the user provided) Password_verify will will read the whole string which is salt+pass together, will use the first characters which is the salt and will use this salt with the plain password the user provided to encrypt it.

Then it will compare the result with the remaining of the salt+hash that was pulled from the database (the remaining now should be the hash.. without the salt).

I hope this helped tou understand why tou get different strings all the time tou use password hash for the same password.

user2399432
  • 738
  • 1
  • 9
  • 17