Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I've read that every good web application should hash passwords. I found many articles about hashing. So I started implementing hashing on my website and then I asked myself why should I do it? When a user sends his or her login (name+password) to the server, the server loads the password of the given user name from database and then compares passwords. There is no way how the user could get password from the database.

Most likely I'm misunderstanding the concept, so can anyone please tell me why anyone should be using hashing?

share|improve this question

migrated from stackoverflow.com Jun 3 '13 at 7:15

This question came from our site for professional and enthusiast programmers.

4  
Before doing any password hashing, please PLEASE go read this answer first. –  lynks Jun 3 '13 at 9:11
    

7 Answers 7

up vote 15 down vote accepted

For any reason, your database may be compromised and its data may be obtained by someone else. If the passwords are in what we call plain text, you will have leaked a piece of sensitive information that your users have trusted you with: their password (which is very likely to be a password shared in multiple services). This is a very serious issue.

Instead of plain text, passwords are typically hashed with an one-way hashing function. If the cryptographic function used for the hashing is strong, then the passwords are much safer, because even if someone gets their hands on your database, it's computationally infeasible to decrypt the passwords (given only the hashes).

On the other hand, the hashed information remains useful to you: Because the same hash function will always yield the same hash for the same input, you can still hash any attempted password and compare the result to your saved hash to verify a user's authentication attempt (without knowing the correct password beforehand).

Of course, just hashing is not enough nowadays. There are dictionary attacks that often make decryption (of hashes created from predictable passwords) very feasible. To counter these attacks, each password is hashed together with a unique randomly generated piece of input (called salt). The salt is stored in plain text in the database and it doesn't have to be secret, because its main purpose is to render precomputed hash dictionaries useless.

Almost all serious platforms use hashing and salting to store their users' passwords (unless they make use of something different but comparably secure that I'm not aware of). Incidentally, this is exactly why you can reset your password in various services but almost never recover it: The hash can be overwritten by the system, but it can't be decrypted.

You should by all means do the sane thing for the sake of your users' security and salt-and-hash your passwords. There are plenty of resources online that explain the process and the pitfalls in detail. One of them is "Secure Salted Password Hashing: How to do it Properly".

share|improve this answer

Your database could be compromised for any number of reasons, it happens all the time watch the news (even to some of the biggest web sites on the web). It's just a safety precaution to your users to hash their personal information in case your DB ever gets compromised for any reason.

share|improve this answer

There is no way how the user could get password from the database.

And indeed as long as this assumption is true there is no reason to hash the password — it's literally a waste of time.

The fly in the ointment is that this assumption does not hold in practice. There are two main ways a password database could be compromised:

  • Attackers manage to gain unauthorized access to the live server. A typical example is SQL injection in some buggy web application.
  • A backup of the database is accidentally exposed to the internet or physically lost.

If the password database is leaked in such a manner, and the passwords are in plain text, then anyone who can access the leaked database gets to read the passwords. You might think then of encrypting the password — but that doesn't really help, because the application needs to be able to encrypt the key, and most attacks that leak the database can also leak the key.

So instead of storing the password directly, you should store a hash of it. The general idea of a hash is that you can compute the hash from the password but not the other way round. Cryptographers have come up with algorithms to do this. An added twist is that not just any cryptographic hash will do, because the attacker can try to compute hashes by brute force (“Is it password? No. swordfish? No. Tr0b4dor&3? Yes!”). So a good password hash has two additional qualities:

  • It must be slow, so that it'll take a long time for the attacker to go through all likely possibilities.
  • It must incorporate a unique element (called a salt), so that the attacker can't do a lot of precomputation that make it efficient to crack lots of passwords at once.

For all the details of password hashing, read How to securely hash passwords?. In practice, call scrypt, bcrypt or PBKDF2 in your programming language or framework's library, with a random salt.

share|improve this answer

Hashing passwords provides defense against your passwords being compromised when a database has been compromised. It does this in two ways, 1. it hides the users passwords by making it computationally impossible to get the password from the hash, and 2. It can slow down the generation of rainbow tables for lookup against known passwords.

Hash functions are one way functions, meaning that if you know the original data you can produce the hash but having the hash won't give you the original string (in theory anyway). The easiest way think of this is to think of the mod function in programming (%), If I were to ask you what values give you n % 6 = 5 there are lots of answers, 5%6 = 5, 11%6 = 5, 16%6 = 5 and so on... but you can't figure out which n I'm using just by knowing that n%6 = 5. Cryptographic hash functions provide this sort of data hiding, except that it's extremely difficult to find collisions (two values that produce the same hash). For example SHA2 provides 128 bits of entropy, meaning that it should take 2^128 tries to find a collision (although SHA2 is a 256 bit algorithm it like all hash functions is susceptible to the birthday paradox).

Because cryptographic hash functions have this property of data hiding, when someone looks at the passwords in your database they typically wouldn't be able to tell what those passwords are just by looking at them

Rainbow Tables

Rainbow tables are tables of pre-hashed passwords. Because most people use easy to remember passwords with low entropy a bad guy could just have a table of known passwords and check your hashed value against what is in the table. To mitigate against that you use a salt, which is just a random string that you concatenate to the password. It's suggested to use a different random salt for each users password. The salt should be generated by passing a random value (for C# you can use RNGCryptoServiceProvider ) into a pseudo random number generator (such as a Hash function) any time a password is created or changes. Lots of programmers think that salt has to be a string of characters, it does not, you can use bytes that are Base64 encoded in your db and just decode them before you do your check. This would change the original string enough to make it so the hash doesn't match what would be in a rainbow table and make it useless to do a simple lookup. Good Cryptographic hash functions have a property called the "Avalanche effect" this basically means that a 1 bit change causes at least 50% of the bits to change after it. So hashing with salt increases your overall security by making it harder to figure out what those passwords are by a simple lookup.

Fast Computation

These days computers are extremely fast, making it feasible to compute a rainbow table on the fly. Because the salt is stored in plaintext usually in another column on the same table as the hashed password, a bad guy who has access to your database can compute a rainbow table on the fly with a known dictionary and the salt you have in your database.

For this case we want a way to make it harder for them to do it. And while many of us programmers toil over making our application faster this is where we would actually want things to go a little slower. Hash functions such as the SHA family are made to hash large amounts of data very fast, so they are not ideal for password hashing. Hash functions such as BCrypt introduce a work factor, a higher work factor causes the algorithm to perform slower so it's extremely hard to generate a rainbow table. As computers get faster you simply increase your work factor and rehash the hash you have. A nice side effect with BCrypt is that it will generate the salt for you, so you don't have to mess with RNGCryptoServiceProvider etc, and if you use BCrypt.NET you won't need an additional column to store the salt as it is part of the resulting string you get back. The idea is to have a work factor that's tuned so a user doesn't notice the delay when logging in, but a bad guy is really slowed down when they are trying to brute force a password or trying to generate a rainbow table on the fly.

share|improve this answer
1  
This is a good presentation, except for the first paragraph. Hashing passwords only defends against one thing: brute force attacks after the database is compromised. It's not two lines of defense, just the one. (Or you could call salting and slowness two lines of defense, but the important point is that the only use of hashing is to mitigate a database compromise, it does nothing about online brute-force attacks.) –  Gilles Jun 3 '13 at 11:46
    
@Gilles Thanks for the clarification, I see your point and agree I'll make an edit. –  nerdybeardo Jun 3 '13 at 13:16

The most basic reason why you hash a password is so that if the stored version of it is stolen it cannot be openly read.

Note that I said the stored version - if the password is never stored in any form (which is unlikely) then there is no point hashing it ever. But it is unlikely (and impractical) that you will never store it, so it should be hashed. You may think that your database is secure but there are some very smart people out there who are way smarter than you.

But you should also note that hashing it alone is largely ineffective - you should also add a salt to it before hashing. This means you add a known (preferably not too predictable) value to the password (anywhere in the password) before hashing it - this helps to slow down the breaking of the password by the use of rainbow tables.

Transmission of the password should be across a connection secured by TLS - ie it should be across HTTPS. This way you can send the entered password in clear text (you should not try to encrypt or hash it at the web page), the server side code then salts and hashes the received password before checking the resulting hash against the salted hash stored in the database.

share|improve this answer

It is for added security. You have to assume the worst case which is that your database will be hacked. If you save your users passwords in plain text along with other data, the hacker will know that this user uses that password. Since most people reuse passwords, they could potentially use it to access other sites with data stolen from you.

That's why it is considered good custom to hash your passwords, and preferably to salt them as well, making it harder for a potential hacker to reverse the hash back to its plain text meaning.

share|improve this answer

If someone crack your database he will get all the passwords but hashed. Since hashing function is not reversible he won't make anything with it.

the more secure way is to compute hash = password + salt

share|improve this answer
    
+1 for the salt –  djf Jun 2 '13 at 13:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.