Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why string hashed with its hash as salt returns the hash?

I was reading up on password security in PHP and I stumbled upon an interesting statement:

Hashing the password with its hash as the salt returns the same hash

Without much thinking, I went on php.net and found that is says the same thing.

Let's look at an example:

crypt("test", "test"); -> teH0wLIpW0gyQ
crypt("test", "teH0wLIpW0gyQ"); -> teH0wLIpW0gyQ

I can totally understand that crypt in PHP generates a one-way hash of the given string.

  1. What I don't understand is how can we obtain the same hash output using two completely different salts?
  2. Does it mean there are possibly other salts that could possibly give me the same hash?

Follow up

Thank you all for your pointers. I can see now that the default behavior is to use only the first two characters of the salt, which totally answers all my questions. Feels like a silly thing, but...

like image 360
ZorleQ Avatar asked Nov 09 '13 21:11

ZorleQ


People also ask

Why do hashed passwords normally include a salt value?

A cryptographic salt is made up of random bits added to each password instance before its hashing. Salts create unique passwords even in the instance of two users choosing the same passwords. Salts help us mitigate hash table attacks by forcing attackers to re-compute them using the salts for each user.

What is the purpose of salt to a hash?

Password hash salting is when random data – a salt – is used as an additional input to a hash function that hashes a password. The goal of salting is to defend against dictionary attacks or attacks against hashed passwords using a rainbow table.

Can you decrypt a hash if you have the salt?

Assuming the salt is very long, not knowing the salt would make it nearly impossible to decrypt hash password with salt(due to the additional length that the salt adds to the password), but you still have to brute force even if you do know the salt.

Should password hashes be salted?

Password hashing makes storage and management more secure, and applies to both salted and unsalted passwords. Salted passwords that are also hashed make it harder for bad actors to crack passwords at scale.


2 Answers

This is done on purpose. Your crypt function, when second argument consists of letters and digits, uses only two first characters of "salt" for encrypting, and those two characters are placed at the beginning of the result. So,

crypt("test", "test");        -> teH0wLIpW0gyQ
crypt("test", "te");          -> teH0wLIpW0gyQ
crypt("test", "tea");         -> teH0wLIpW0gyQ
crypt("test", "temperature"); -> teH0wLIpW0gyQ
etc.

This is done for easy password correctness checking, so that
crypt($password, crypt($password, $salt)) == crypt($password, $salt)

like image 97
Serge Seredenko Avatar answered Sep 20 '22 12:09

Serge Seredenko


1‍. What I don't understand is how can we obtain the same hash output using two completely different salts?

Although you provided different salts to the crypt function, it uses the same salt internally, i. e., te. This is due to how crypt is implemented:

Standard DES-based hash with a two character salt from the alphabet "./0-9A-Za-z".

So even if you provide a salt longer than 2 characters it will only take the first two.

And as crypt’s output contains the used salt prepended to the calculated hash, using a crypt hash as salt results in exactly the same output. And that’s just perfect as then the following can be used to verify a stored password:

crypt($password, $hash) === $hash


2‍. Does it mean there are possibly other salts that could possibly give me the same hash?

Yes. This does also apply to other crypt algorithms like bcrypt.

like image 44
Gumbo Avatar answered Sep 20 '22 12:09

Gumbo