Reputation: 55594
I've read through many of the questions on SO about this, but many answers contradict each other or I don't understand.
You should always store a password as a hash, never as plain text. But should you store the salt (unique for each user) next to the hashed password+salt in the database. This doesn't seem very clever to me as couldn't someone gain access to the database, look for says the account called Admin or whatever and then work out the password from that?
Upvotes: 12
Views: 2423
Reputation: 8920
A lot of people are saying "to stop rainbow tables" without explaining what rainbow tables do or why this stops them.
Rainbow tables are a clever way of precomputing a large number of hashes and storing them in less memory than would naively be required, and you can use them to very quickly reverse a hash. Tables for bare functions such as hash = md5(password)
and hash = sha1(password)
are common.
However, they can be generated for ANY hash function which can be described as output = f(input)
. If you use a site-wide salt for all user passwords, for example hash = md5(salt+password)
, you could construct a function f
, f(password) = md5(salt+password)
. Therefore you could generate rainbow tables for this function, which would take a long time, but would then let you crack every single password in the database very rapidly.
If the salt is different for each password, you can't generate a rainbow table that will crack all passwords in the database. You could generate a new one for every user but that would be pointless - naive brute-forcing would be no slower. So having a seperate salt for each user stops the rainbow tables attack.
There are several ways to do accomplish this. Popular ways include:
hash = hashfunction(salt + password)
hash = hashfunction(salt + password + user_id)
for examplehash = hashfunction(global_salt + user_salt + password)
Having a global salt could add a little extra complexity to cracking the passwords, as it could be stored outside of the database (in the code, for example) which attackers may not gain access to in the event of a database breach. Cryptographically I don't think it adds much, but in practice it could slow them down.
Finally, to answer your actual question:
Storing the salt alongside the user data does not weaken the hash. Hash functions are one-way: Given the hash of a password, even an unsalted one, it is very difficult to find that password. The motivation behind salting is not to make an individual hash more secure, but to make the collection of multiple hashes more secure. There are several vectors of attack for a collection of unsalted hashes:
123
, password
, god
) and seeing if any exist in the database, and then compromise those accountsUpvotes: 26
Reputation: 31
Well well well .. so many discussions ... so much information. so many questions ... i see that after all the questions are answers here is the summary.
Here is my understanding.
Ok..though not fully complete, but my point is bad guys take lot of time .... but good guys are a step ahead to ensure that they know the technology which bad guys will be using to crack. So just devise a better technology by time.
Take care ....
Upvotes: 2
Reputation: 826
Salt is used to increase the time that an attacker would have to spend to find a password matching the hash stored in database. Typically lookup table such as rainbow table (see http://en.wikipedia.org/wiki/Rainbow_table) is used to achieve this.
What costs time is not the lookup itself, but the time to compute the rainbow table. Adding a salt forces the attacker to recompute a new rainbow table, even if it is known by the attacker who would compromise the database
Upvotes: 6
Reputation: 25559
If you don't store the salt, how will you check if the correct password was provided?
Upvotes: 1
Reputation: 56450
Well first of all, the primary purpose of the salt is to disable brute-forcing of the passwords, for example it prevents the usage of rainbow tables for quick compromising of a password.
Even if an attacker gains access to a database, it's not that easy to work out the real passwords from the salts (especially if you don't have the code and don't know how the password is hashed). However what I like to do for additional security is to also hash a password with a static hash that is specified in the code. This way it's not enough that you compromise the database. An example of such method (in PHP):
$hashed_password = sha1($user_password . $user_salt . $static_salt);
$user_salt
is the salt in the database unique to each user, $static_salt
is the salt specified in your code's settings somewhere.
Upvotes: 2
Reputation: 101251
The salt is meant to disturb existing rainbowtables. It's no security threat to know the salt. If you know the salt, you would still need to know the password.
Upvotes: 3