Reputation: 43
If I have a random, 16 character long, alphanumeric salt (varying case) that is generated and stored per user, do I need a site wide salt as well?
In other words, is this good?
sha1($user_salt . $password)
should I do this instead?
sha1($user_salt . $password . $site_salt)
Also,
At the moment, I have an encrypted cookie, that looks up a session in a DB. In this session, there is an user_id and an user_token. I then query the DB using the user_id -- if the sha1 of the user_id+hash in DB === user_token, then the user is allowed through.
I do the second query for the user_id on every page load so that if I delete, ban or change the password of an user, the action has immediate effect.
This is what I've come up looking through websites and questions here. What do you think? Did I miss something?
I need to add role checking but that would probably add yet another query (3rd one just for auth). Any tips?
Upvotes: 2
Views: 267
Reputation: 1700
At the moment, I have an encrypted cookie, that looks up a session in a DB. In this session, there is an user_id and an user_token. I then query the DB using the user_id -- if the sha1 of the user_id+hash in DB === user_token, then the user is allowed through.
I do the second query for the user_id on every page load so that if I delete, ban or change the password of an user, the action has immediate effect.
Commenting only in case there is something wrong here that no-one else caught:
It sounds a lot like you are storing the password or a password hash in the cookie, rather than storing a session identifier in the cookie. I would recommend against that. The biggest reason is that using a derivative of the password like this stands a good chance of turning the derivative into a password equivalent.
In other words, all an attacker needs is the hash of the password, and not the password itself in order to effectively authenticate. The problem with this is that the hash of the password doesn't change except when the password changes (not under your control), whereas a session ID changes whenever you darn well please.
My recommendation (if you want a session to be sensitive to password changes) is to change the session ID whenever the password changes.
Upvotes: 0
Reputation:
sha1($user_salt . $password)
This is very common, but it isn't good.
A typical end user password is ~8 characters long, and mostly keeps to the 7-bit ASCII character set. So a typical password is about 64 bit of random data or less. Modern parallel brute-force attacks can defeat this, by simply trying out all possible passwords. Using a SHA256 or SHA512 instead does not materially change the outcome because the end users password is the limiting factor.
From my reading here at Stack Overflow, there seems to be 2 schools of thought regarding password storage:
At the moment, I have an encrypted cookie, that looks up a session in a DB. In this session, there is an user_id and an user_token. I then query the DB using the user_id -- if the sha1 of the user_id+hash in DB === user_token, then the user is allowed through.
One main point of secure session handling that you're not mentioning is SSL everywhere to guard against Sidejack. And User IDs are generally not good for security, because they are often guessable (auto-incrementing primary key) or they end up in URLs etc by mistake. Instead of rolling your own session handling system, isn't there a peer reviewed codebase you could use?
Upvotes: 0
Reputation: 4505
Utilizing a "site-wide" salt might be useful. This means that not only would your database have to be compromised, but your source code would have to be as well in order to really understand your password scheme.
I call this a "salt" and "pepper" approach. The salt stored per user, the pepper is the site-wide value.
Salt
The purpose of a unique per-person salt is to invalidate rainbow tables. The salt is typically stored in the database and either appended or prepended to the password. Someone aware of this can still run dictionary based attacks per user, but the good thing about a salt is that they cannot use a rainbow table for such common dictionary terms.
Pepper
The purpose of "pepper" as I call it is to add a potentially unknown string to every password which means a brute force dictionary attack taking salt into consideration would just plain miss because of lack of pepper. It also means that a brute force per character check would need to "discover" a longer password which could take longer. These benefits disappear as soon as the pepper is discovered.
Upvotes: 1
Reputation: 10414
It sounds like you're trying to recreate DIGEST-MD5 or SCRAM. Both of these allow you to store a non-password string that is unique to your site and challenge/response with another party to verify that they have the password string, without sending the password string on the wire.
Upvotes: -1
Reputation: 490123
No, you do not need a sitewide salt. The salt is used to make rainbow tables useless. A site wide salt could be used if you really wanted to, but I don't think it is necessary.
I think if your database was compromised and someone realised your passwords were hashed with a salt, they'd move onto the next site that had less security in place (unless of course you are running a site worth hacking - chances are you aren't :P )
Upvotes: 7