RS7
RS7

Reputation: 43

Passwords, salts and auths

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

Answers (5)

Slartibartfast
Slartibartfast

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:

  1. You mention that the cookie is encrypted
  2. You meantion sha1 of user_id+hash
  3. You mention a second query (it isn't clear to me what either query is) that is sensitive to password changes.

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

user84609
user84609

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:

  1. You should use a computationally expensive approach like BCrypt or scrypt. That way brute force attacks become infeasible. This works, at the expense of requiring much more CPU power from your server when a user logs in. See this excellent article for an overview of the rationale.
  2. The second school of thought is that while BCrypt and scrypt certainly work, they are undesirable for multiuser apps because they take too much CPU time -- making the end user wait, or potentially opening up for a denial-of-service attack by sending lots of authentication requests. See the lengthy discussion here (be sure to read the comments as well).

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

M2tM
M2tM

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

Joe Hildebrand
Joe Hildebrand

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

alex
alex

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

Related Questions