How to check password in database if password was encrypted with "salt"?

Viewed 2454

I've read than a method "salting a password" improves password protection. But I don't understand how to check the password if it is stored in a complicated form. I assume that the user's password is encrypted on the client then its hash code compares with hash code in the database. I have no experience in web development. I am just learning ways of web security.

2 Answers

I will try to give some intro since you told that you are currently learning it. And will try to make it short as much as possible.

  • Salt is a random string that we generate and add to the plain password / passphrase. It could be stored as plain in the database right next to the Hash Value.
  • Hashing is a way to map a data to a value with a fixed length. This value is called Hash Value or checksum. Hashings are one-way. MD5 and SHA256 are some examples for hashing algorithms.

Benefit of salt

What we are doing here is basically making sure that all users have unique passwords (in hash output). This will avoid possible attackers who captured the user data to compute multiple user's password at the same time.

Another saying, when someone looks at the all usernames and passwords, they will not be able to say which users use the same password.

The following table helps us to understand it better.

| username | salt             | plain-password |salted-password-to-be-hashed | hashed-password                                                  |
|----------|------------------|----------------|------------------------------|------------------------------------------------------------------|
| user1    | db97913154884d72 | password1      | password1db97913154884d72     | 5027a576d161385ddcc72e47280f85729fc3ba5e48e0a018e2f68dc7d13e93cc |
| user2    | 8fc2884d127fd40b | password1      | password18fc2884d127fd40b    | 6069e0e5a06d41ed0ffb06d0c0e26dd7dea3cb14de80e4075848d3217b40b783 |

The following steps demonstrate a basic way to store and authenticate.

How to store? (register)

  • The plain-password comes to your back-end application from the client through https.
  • The back-end application generates a salt and append (or prepend) it to the plain-password.
  • Then, computes the hashed-password using a hashing algorithm (such as SHA-256, MD5 etc)
  • Lastly, stores username, salt and hashed-password into the database. (Never stores plain-password and / or salted-password-to-be-hashed.)

How to Authenticate?

  • The plain-password comes to your back-end application from the client through https.
  • The back-end application gets user specific salt from the database and append (or prepend) it to the plain-password.
  • Then, computes the hashed-password using the same hashing algorithm and compares it with the stored one.

A bit more advanced:

You could also add a second salt called pepper. This is another random string to be added to the plain password (pepper + plain-password + salt). However here, pepper is stored in an another datasource, not next to salt and hashed-password.

Salting makes it more difficult for an attacker to re-create the original password. So yes, it is a form to improve the password protections. But you need to look at it from different perspectives.

As for your questions:

I don't understand how to check the password if it is stored in a complicated form.

You don't. When your user creates the password, you compute the hash and store only the hash. When they log back in, you compute the hash again and if it matches, you know that the user provided the same password.

I assume that the user's password is encrypted on the client then its hash code compares with hash code in the database.

There are methods where the user never even sends the password to the server, but for a traditional username+password login, the user sends the password in clear text (hopefully via https) and the server computes the hash on the server side.

To go into a bit more detail

You do not want to stare the clear text password, because the password is a secret only the user should know.

Hashing - in general - is a better way to store the password. It's eleganz, because you only save a checksum and when the user logs in, you compute the hash again and check if they match. This is better, because you don't store the password and thus can not lose it.

BUT: if two users have the same password, they also have the same hash. This is bad, because now you know more about the password than you should and for an attacker this is interesting, because cracking this password will give them access to more than one account.

Even worse, there are pre-computed lists for common words ( so call rainbow tables). 5f4dcc3b5aa765d61d8327deb882cf99 for example is the MD5 hash for password. There are websites like crackstation where you can reverse look up hashes.

Combine these two weaknesses and you understand why a simple hash is not enough to adequately protect a password.

This is where the salt comes in. If the server adds to each and every password some additional, unique bits of data, two users with the same password now get different hashes.

| Salt  | Password | MD5                              |
|-------|----------|----------------------------------|
| salt1 | password | 421ec89b160730497225a2bfac63305c |
| salt2 | password | 6b60d583eb2b0888b91c8fe72d652ed1 |

In addition, this makes it much harder for a rainbow table to pre-compute common words because it would need to precompute also all possible salts.

The server of course must remember the salt it used, otherwise it would not be able to compute the same hash again when the user logs in.

If an attacker gets your database, they would have the hash and the salt. While they can't use rainbow table any more, they still can start an attack by guessing the password. This is still a lot harder, because they need to guess every password for every user with their personal salt.

You can make it even more difficult by using a hash that is on purpose inefficient, eg. PBKDF2, Argon2, BCrypt *. A slow password function has little to no effect if a user who knows the password logs into the system. A few more milliseconds don't matter here. But if an attacker who needs to compute millions and millions combinations now also has to use a hash function that is 100 times slower than a general purpose hash, they need 100 more resources to attack the hash. And hopefully that makes the attack unattractive to them.

*) as of this writing.

Related