Salting: Is it reasonable to use the user name?
Asked Answered
C

6

10

I am debating using user-names as a means to salt passwords, instead of storing a random string along with the names. My justification is that the purpose of the salt is to prevent rainbow tables, so what makes this realistically less secure than another set of data in there?

For example,

hash( md5([email protected]), p4ss\/\/0rD)

vs

hash( md5(some_UUID_value), p4ss\/\/0rD)

Is there a real reason I couldn't just stick with the user name and simplify things? The only thing my web searching resulted was debates as to how a salt should be like a password, but ended without any reasoning behind it, where I'm under the impression this is just to prevent something like a cain-and-able cracker to run against it without being in the range of a million years. Thinking about processing limitations of reality, I don't believe this is a big deal if people know the hash, they still don't know the password, and they've moved into the super-computer range to brute force each individual hash.

Could someone please enlighten me here?

Complected answered 27/7, 2010 at 19:12 Comment(1)
I have found a great related article. web.archive.org/web/20080822090959/http://www.matasano.com/log/…Complected
M
13

You'll run into problems, when the username changes (if it can be changed). There's no way you can update the hashed password, because you don't store the unsalted, unhashed password.

Mcintyre answered 27/7, 2010 at 19:17 Comment(8)
I like this reason as it complicates what my system is doing, but I don't see why I can't run a re-set of the password at that moment (it could even be as simple as the "verify change with your password" screen).Complected
You can also use registration date. It's not so likely to change :)Newmodel
@chris_I: I agree with user257493, if they change the username, just store a newly encrypted password at the same time.Dunseath
@user257493 Yes, if your users are ok with that, and if the salt has to be transmitted openly anyway, then it's almost as good as a random salt. (It's theoretically possible, that somebody precalculates a table with common user names.)Mcintyre
@m01 I really like your idea, it's much less likely to be known the microsecond time that the sql string building took place on my server. @chris_I The design right now does have them in the open, which is somewhat unfortunate (and why I'm asking).Complected
@user257493 I agree with David Thornley, that it's ok to have them in the open. The secret is the password. Trying to add security by hiding the salt is a little bit obscure anyway. I like m01's idea, too!Mcintyre
I can't believe this got 9 votes and correct answer. If username changes I would assume you are requiring password to do so. Thus you have old username, new username, and current password. Validate user, update username, rehash password with new hash.Plumbaginaceous
@theUnhandledException: Try it on stackoverflow: When the username changes, it doesn't require a password change. That's pretty usual, because from a user's perspective, it's not easy to see why a password change would be required in this case. Of course, you can implement it that way, if your users are ok with that (like I said in a previous comment).Mcintyre
D
3

I don't see a problem with utilizing the username as the salt value.

A more secure way of storing passwords involves using a different salt value for each record anyway.

If you look at the aspnet_Membership table of the asp.net membership provider you'll see that they have stored the password, passwordsalt, and username fields in pretty much the same record. So, from that perspective, there's no security difference in just using the username for the salt value.

Note that some systems use a single salt value for all of the passwords, and store that in a config file. The only difference in security here is that if they gained access to a single salt value, then they can more easily build a rainbow table to crack all of the passwords at once...

But then again, if they have access to the encrypted form of the passwords, then they probably would have access to the salt value stored in the user table right along with it... Which might mean that they would have a slightly harder time of figuring out the password values.

However, at the end of the day I believe nearly all applications fail on the encryption front because they only encrypt what is ostensibly one of the least important pieces of data: the password. What should really be encrypted is nearly everything else.

After all, if I have access to your database, why would I care if the password is encrypted? I already have access to the important things...

There are obviously other considerations at play, but at the end of the day I wouldn't sweat this one too much as it's a minor issue compared others.

Dunseath answered 27/7, 2010 at 19:34 Comment(9)
The password is very important, because many users use the same password for multiple systems!Mcintyre
hashing != encryption, hashing is more a service to your users. Since hashing by definition is not reversible you are protecting your users password from even possible insider snooping. Encryption on the other-hand cannot protect from snooping by insiders with a key. Technically, if you don't plan on your database ever being stolen why not just store the passwords in cleartext?Panfish
@joshperry: I was actually arguing the other way around. You should plan on your database being stolen which is why the whole thing should be encrypted, not just the passwords.Dunseath
Chris, usernames are entirely predictable, so they'd be vulnerable to a rainbow table generated for that username.Anuran
@Steven: But the rainbow table would only apply to that one record in this one database. The purpose of a salt is to prevent rainbow tables from being applied to ALL the records. In effect, a rainbow table would have to be compiled for each username. This is simply not feasible as you are talking about generating between 8GB and 80GB of rainbow data PER LOGIN NAME. The time it would take to do this is nontrivial and goes up with password length.Dunseath
@Chris: You're a nice guy, but you don't have a criminal mind. You only need to hack one account, which has a predictable name: Administrator.Anuran
@josh: Good point. In fact, the biggest vulnerability the user has is that they keep transmitting their password. If the system sends them their salt, they can do the hashing on the client side and send only the hash over the wire.Anuran
@Steven: Provided "administrator" is an actual username in your system, then I agree... Regarding the idea of only passing the hashed version, this is really no more secure than passing in the "plain" password for hashing server side. Either is vulnerable to replay.Dunseath
@Chris: Storing the salted hash prevents an insider from figuring out the users' passwords, but it doesn't stop them from subverting the logon process to log the password before hashing. On the other hand, if we give the salt and a nonce to the client, have the user enter their password, hash it with the salt, and then hash it with the nonce using HMAC...Anuran
P
3

If you use the username as password and there are many instances of your application, people may create rainbow tables for specific users like "admin" or "system" like it is the case with Oracle databases or with a whole list of common names like they did for WPA (CowPatty)

You better take a really random salt, it is not that difficult and it will not come back haunting you.

Pesthole answered 2/8, 2010 at 13:3 Comment(1)
PBKDF2 provides protection from a lookup table. While your site may have "known" usernames you have two other elements. The static salt on PBKDF2 function and the number of iterations. Thus "admin" on my site will generate a totally different derived salt than "admin" on your site.Plumbaginaceous
P
1

This method was deemed secure enough for the working group that created HTTP digest authentication which operates with a hash of the string "username:realm:password".

I think you would be fine seeing as this decision is secret. If someone steals your database and source code to see how you actually implemented your hashing, well what are they logging in to access at that point? The website that displays the data in the database that they've already stolen?

In this case a salt buys your user a couple of security benefits. First, if the thief has precomputed values (rainbow tables) they would have to recompute them for every single user in order to do their attack; if the thief is after a single user's password this isn't a big win.

Second, the hashes for all users will always be different even if they share the same password, so the thief wouldn't get any hash collisions for free (crack one user get 300 passwords).

These two benefits help protect your users that may use the same password at multiple sites even if the thief happens to acquire the databases of other sites.

So while a salt for password hashing is best kept secret (which in your case the exact data used for the salt would be) it does still provide benefits even if it is compromised.

Panfish answered 27/7, 2010 at 19:59 Comment(0)
B
1

Random salting prevents comparison of two independently-computed password hashes for the same username. Without it, it would be possible to test whether a person's password on one machine matched the one on another, or whether a password matched one that was used in the past, etc., without having to have the actual password. It would also greatly facilitate searching for criteria like the above even when the password is available (since one could search for the computed hash, rather than computing the hash separately for each old password hash value).

As to whether such prevention is a good thing or a bad thing, who knows.

Basically answered 27/7, 2010 at 20:0 Comment(1)
Which is why any derived salt should be strengthened via PBKDF2. Using a custom number of iterations and custom site salt will make your "username salts" unique to your site.Plumbaginaceous
P
1

I know this is an old question but for anyone searching for a solution based on this question.

If you use a derived salt (as opposed to random salt), the salt source should be strengthened by using a key derivation function like PBKDF2.

Thus if your username is "theunhandledexception" pass that through PBKDF2 for x iterations to generate a 32 bit (or whatever length salt you need) value.

Make x pseudo random (as opposed to even numbers like 1,000) and pass in a static site specific salt to the PBKDF2 and you make it highly improbable that your username salt will match any other site's username salt.

Plumbaginaceous answered 15/11, 2010 at 15:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.