I've been using password_hash('password', PASSWORD_DEFAULT) for an internal system, and while I was testing the code, I saw that it generated different hashes for the same input.

Why does this happens, and how do password_verify() identify another hash as the same password if the hashes are different?

Is there an explanation about it's 'safeness'?

  • 3
    It's likely a duplicate, but the short answer is. Because password_hash() automatically generates a salt.
    – user163495
    Oct 10, 2019 at 13:57
  • @MechMK1 definitely it is the question I had. I searched but didn't find this question. Thanks!
    – Kelvin
    Oct 10, 2019 at 15:23

2 Answers 2


like the documentation of password_hash states, a unique salt is being calculated for each time it is called.

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.

(source: php manual - password_hash)

Additionally the used options of the hashing process are stored in the generated hash itself(salt,cost,algo) so the password_verify has all information's it needs to verify if a plaintext matches a hash without being able to decrypt it.

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.

(source: enter link description here)

This also explains why the start of most hashes are identical. For example depending on the cost and algo used your hashes might always start with something like $2y$10$ and from then on differ. This behavior can however change between different frameworks, algorithms or other factors, so take this only as a example of how the cost and algo can be saved in the resulted hash.


If you read the documentation on php.net you can see that this function generates a secure salt every time you use it. So if you are using the same input there will be a different output because of this random salt.

In the password_verify section of your code the new salt will be used. The hash will be identical and a user is able to login.

If you want that your hash stays always the same you need to deliver an own salt with the option salt to PASSWORD_BCRYPT. This is not considered as secure if you are not knowing what you are doing. So i would prefer the automatically generated salt.

  • Not only do you need to know what you are doing for a manual salt, it is deprecated since PHP 7.0.0 and might be removed some time in the future, making it not the best option.
    – Nico
    Oct 10, 2019 at 14:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.