Password_hash doesn't generate the same hash per unique input

I’ve used password_hash() and password_verify() so far without any problem, but writing something as simple as echo password_hash('123456',PASSWORD_DEFAULT); makes me scratch my head. I don’t know even the security-101 but all the hashing functions I’ve seen so far generate a same hash for the same input, but this function is generating a new hash every time the script is run.
One guess that currently comes into my mind: A random salt is generated internally and is attached to the password, and then the hashing occurs. But if that is the case, then there must be no ways later for the password_verify function to know what random string was used at first as the salt when generating this hash.
So how is this function working? Is my understanding of hashes to be unique per input wrong?

The password_verify docs explain things a bit.

As you speculated, each call to password_hash does indeed generate a unique salt. The salt is then encoded into the hashed result. As a result, the password_verify can extract the salt.

Having a unique hash each time you call password_hash make it a bit harder to brute force a password guesser.

2 Likes

So you mean encoding of salt into the hash is done in a way that decoding of it is then possible for the password_verify to get the used salt? So this kind of encoding must be not one-way, then is it safe? (Maybe I didn’t understand your answer correctly)(Of course, I understand your last point. Thanks.)

This is why you must always use password_verify to verify.
Some try things like:-

if(password_hash($_POST['password']) === $row['hash']){ $valid = true ;}

But that’s wrong and won’t work, as the salt is different every time.

Yes, it is much safer than the older hashing methods, that’s why it is now the standard and the old ones should no longer be used.

1 Like

Yes, the actual hashed password along with the salt, algorithm and cost are all encoded into the string returned from password_hash. So password_verify can extract them. But the password itself is still a one-way hash value. No way to extract the original value from it.

This saves you from having to explicitly generate and store the salt and it allows you to save the algorithm used. At the same time, someone trying to crack the password will have to generate the complete hash for each attempt.

It is really no different then what was done before password_hash came along. You just don’t need to keep track of the salt.

2 Likes

Now I understand it. Thanks.

You also might want to consider the security aspect of it. If you were to generate a hash the contains the same hash if the passwords are the same. Do you think that’s really safe? If the hashing algorithm is really weak, when the passwords are cracked, that means that the other accounts that have the same passwords are also compromised. Instead of having 1 user lose their account, now you have say 50 users. If those users don’t know any better and use the same passwords on all their other social accounts, guess what will happen? Now their whole social media accounts are compromised. Do you see how a chain reaction going on here? If you were to generate a completely new hash every time you reuse that password, then it’s a whole lot safer than generating the same hash for the same passwords.

1 Like

Have a look at this website There you see, pushing the generate button, with the same password will return a different HASH each time. Which is only good in my opinion.

2 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.