Hi,

Seem to be having problem with the password_hash() as it keeps changing the hash value of the same password. Why ?
When each time I refresh the page, the $password_hashed value changes! Why ? The $password is still the same who's value is: '123'.
And password_verify($password,$db_password) always echoes '1' (TRUE). How so, since the $hashed_password value changes each time ? Odd!

Try this code in your browser and see for yourself.
Refresh the page on each occassion and see what you get echoed!

echo 'password: ' .$password = '123'; echo '<br>';
echo 'password hashed: ' .$password_hashed = password_hash($password,PASSWORD_DEFAULT); echo '<br>';
//$db_password or database password is now the hash: $2y$10$cie0yEEiLdJkK3IDj8ABXO/vTMvR3F3twO2SVY1VC6D3zP1Fp/xPW

echo 'db password: ' .$db_password = '$2y$10$cie0yEEiLdJkK3IDj8ABXO/vTMvR3F3twO2SVY1VC6D3zP1Fp/xPW'; echo '<br>';
echo password_verify($password,$db_password); //echoes '1' (true).

I understand that the hash value changes each time due to the SALT changing each time on page refresh but how will the password_verify() know which SALT to use on each occassion to decrypt the hash ?

Recommended Answers

All 7 Replies

The salt is encoded inside the hashed password.

@rproffitt
@dani

I understand what you are saying. That, if someone hacks into my db then they won't find the salt since php uses it's own salt by default and salts change each time as no good using the same salt because if there is only one salt then it would be easy to figure that out in 10 secs. And no need for me to create any salts to insert into db as php uses the built-in salts to save our salts from falling into hackers hands extracted from our DBs.
But my original question was, if php by default uses it's own algo to create the salt (where salt changes each time) then how does php know which salt to use (to dehash the password) during logging in time ?
As far as I am concerned, php interpreter might have 10k salts built-in. During registration, it might use the 1st salt and hash the password. But during logging in time, it might check the hashed password against, say salt number 999 and not against number 1. In that case, since it's using a different salt this time (during logging in) there will be no password matches. That was my concern.
Or maybe, php interpreter or password_verify() checks against all available salts that php interpreter uses by default, in our case check against all the 10k salts ? This is likely to be the case.
I think you now understand my question and understand why I opened this thread. My question is very basic. Manual should have answered it so programmers do not get confused to how the password_verify() guesses & uses the right SALT.

EDIT:
I now suspect, the salt number (in our case 'salt number 1') is added to the hash during hashing time.
And when it is time to dehash the password during account login time, the password_verify() checks the hashed password and finds the part of the code that signals which salt number is being used here (eg. salt number 1) and then uses that built-in salt (salt number 1) during password dehashing. That way, no need for php interpreter to check the hashed password against all available SALTS that are built-in to the php interpreter. Do you think I am correct ?

commented: +1 for detective work but the salt is further down the string and very big. The 2y is the algo. would be recognised by any password hashing program +9

I understand what you are saying.
But my original question was, if php by default uses it's own algo to create the salt (where salt changes each time) then how does php know which salt to use (to dehash the password) during logging in time ?

I think you're misunderstanding what I was saying. When using password_hash(), the encrypted string that you ultimately save in your database contains encrypted data that includes the salt, encryption method used, as well as the user's encrypted password that uses that salt and encryption method. When you call password_verify() and you pass into that function the encrypted string, you are passing in all that information.

Update: Yes, your edit is more or less correct.

I think you should never echo the hased password and save the hashed password in db as blob and decode it only for verification cause when you password_verify($pas, $hashed), 1st checks dictionary depending on the algorithm you use then salt and then hashed algorithm after that it changes the salt then execution ends. So yeah if you echo it it changes everytime but still outputs true cause its buffered so not a good ideea to echo hashed pass with salt.

I use bcrypt passwords which look exactly like that.
The first part of the string says how complex the hashing is, then followed by the salt then the hash.
It generates completely different each time so you have to evaluate it with the verify function each time. Its designed to be slow on purpose to prevent brute force attacks, the "10" indicates complexity it gets exponentially longer as it goes up.
On my server around 10 takes about 50ms to solve I think around 14 or 15 goes up to 1 second means a dictionary of 10million would take 10mil seconds, depends how much you want to protect that login.
Bcrypt

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.