The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

salting passwords

where/how do you store the salt for a password? putting it in the database doesn't seem to make sense, because if someone hacks the db, they can get the salt.
Tuesday, January 09, 2007
The traditional unix approach is to store the salt in the leading characters of the hashed password.  Remember, a hash salt is not a "key" -- having it doesn't let you reverse the hashing process.  It exists to make sure multiple occurrences of the same password hash to different values and to make rainbow tables impractically large.

In general there's very little you can do once someone has your list of passwords, no matter what form it's in.  It's one of the fundamental tradeoffs for shared-secret based authentication.
Tuesday, January 09, 2007
To digress a little -- What you really need to think about is what you are protecting.  You aren't protecting your data, if someone hacks the database, they already have the data.  What you are protecting is essentially identity theft.  You don't want someone to be able to impersonate someone else.

A quick and dirty way to impersonate someone else is to steal their user name and password.  Since the password is hashed, even if you steal it, you a still a long way from getting the password.  One way to proceed is to brute force the hash.  The salting technique above will mean that an attacker will have to brute force each account individually instead of trying one password and seeing if anyone has that hash.  BTW, a rainbow table will still get all of the passwords instantly if it sufficiently large to account for the full spce of likely passwords and salts.  The only defense against pre-calculation is a larger password key space (require longer passwords).  You can easily rainbow SHA-512 on a flash drive if the system is stupid enough to only allow 4 character or smaller passwords (like PIN numbers).  Using a huge salt will effectively make the password space larger, so a 128-bit or larger salt will help avoid rainbow tables, but a small salt is useless.

However, a second attack vector is for someone to copy the password hash of a known user over top of any other user.  The prepend technique won't help against this vector.  One defense is to use the primary key value as the salt to make it impractical to copy.  Of course then they could just swap keys between the two rows, but I haven't yet figured out how to make that more difficult.  So, another idea is use the username as the salt.  I'm sure someone will think of a successful attack against this, but this is the process we must go through to implement effective security.

Remember "A security system is only protected against all of the attacks that the designers consider."  If you don't think of what you are protecting against, you probably aren't protected against it.  That is why open security standards tend to be excellent while the proprietary ones often suck.
JSmith Send private email
Tuesday, January 09, 2007
"So, another idea is use the username as the salt. "

That's a nice technique. In all the articles I've read about using salt values I've never seen one that mentioned using something already in the record itself. Makes total sense. Maybe I'm just not reading the right articles!

See, you learn something new every day! Thanks for the tip.
Tuesday, January 09, 2007
Yeah, good one. I might use it. :-)
Wednesday, January 10, 2007
I usually use a combination of values already present, such as both the primary key and the username.  What really matters is that what was used for the salt is something that doesn't change.

In addition to the values in the database record, I also use a global salt value that I store in a config file.  Make sure you name the file something other than salt. Heh.
Jeremy Wood Send private email
Wednesday, January 10, 2007
In .NET 2.0 I would use the built in features for encrypting configuration data, to store the salt, in the same way you store passwords for connection strings to databases. See link for details.
Wednesday, January 10, 2007
I posted somewhere else recently about using the username as the salt and no one ever responded.

The traditional approach is to use two characters which seems to me to be much to small these days. Using the username creates a much bigger search space and also still gets you uniqueness of the hased value.

I'm guessing that the traditional approach comes from the days when computers were much slower and disks were much smaller; and people just keep doing it that way.

I can't think of a problem with using the username as the salt.
am i wrong
Friday, January 12, 2007
A potential issue of using the username as the salt is that it reduces the search space somewhat.

For example, you almost certainly wouldn't have any user names like 4j45uiw48u, right? You'd be more likely to have at least one of "Admininstrator", "Admin", or "root". So someone generating a pre-computed password table could just stick to "likely" salts: well-known usernames, combinations of the most popular last names with different initial letters, etc.

Of course, that's only going to be an issue if your "username as salt technique catches on, otherwise, who'd take the time to generate the table?
Mark Bessey Send private email
Friday, January 12, 2007
As jeremy says, it's critical that whatever you use for the salt not change.  Will users never be allowed to change their names, or just in this version?
Just base64 encode a few random bytes.  The extra storage space won't kill you.
bmm6o Send private email
Friday, January 12, 2007
Once again, it depends on what you are defending against.  If you are defending against offline password recovery -- use a large and random salt.  If you are defending against password replacement, use the username.  If you are defending against both, do both.  Don't wory about complexity, hash algorithms are rediculously simple and efficient.  I've seen MD5 implemented as 100 or so bytes of assembly that runs in microseconds on a small input.  Modern algorithms are just as fast.
JSmith Send private email
Friday, January 12, 2007

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz