Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

The author of http://stackoverflow.com/a/477578/14731 recommends:

DO NOT STORE THE PERSISTENT LOGIN COOKIE (TOKEN) IN YOUR DATABASE, ONLY A HASH OF IT! [...] use strong salted hashing (bcrypt / phpass) when storing persistent login tokens.

I was under the impression that login cookies served two purposes:

  1. UX benefit: don't ask the user to login once per request
  2. Performance benefit: don't need to run a slow algorithm (like bcrypt) per request

It seems the author is invalidating the second point, which makes me wonder: why bother with authentication tokens at all? Instead of mapping the username/password to a randomly-chosen authentication token, why not simply pass the username/password per request using a httpOnly, secure cookie?

Assuming we accept the author's recommendation and use bcrypt per request, what's the advantage of using an authentication token instead a username/password?

share|improve this question

1 Answer 1

up vote 6 down vote accepted

When you use an "authentication token", the simple presentation of that token by the client grants access (as long as the token is deemed valid by the server). If you store the tokens "as is" in your server's database, then an attacker who could get a glimpse at your database will immediately learn all the tokens, allowing him to send requests in the name of all users for whom a valid token still exists in the database. This is bad. Hence the recommendation of storing only a hash of the authentication token.

The advice about bcrypt for authentication tokens is misguided. Bcrypt, like all functions dedicated to password hashing, is meant to be used for passwords. Passwords are weak; they are vulnerable to dictionary attacks. To cope with their inherent weakness, the password hashing function must be salted (to prevent parallel attacks and precomputed tables) and must also be awfully slow (through a huge number if internal iterations). This makes password hashing functions expensive. So you don't want to use a password hashing function unless you need it, e.g. to hash a password.

An authentication token is not a password; it is a random value which was generated and remembered by a computer, without any human brain involved in the process. As such, if you generated the token properly (at least 128 bits, obtained from a cryptographically secure PRNG), then there is no need for salts or iterations; just use a plain hash function (even MD5 would be fine there). This will be more efficient.

As for using a random authentication token instead of login+password for each request, there are two main reasons for that:

  1. Performance: as explained above, an authentication token can be verified safely with a simple hash, which will be vastly more efficient than a heavy bcrypt call. You want to keep your precious CPU cycles for when they are really useful, in particular when applying bcrypt to an actual human-managed password.

  2. Client-side storage: the authentication token will be stored on the client as a cookie value. If the login and password are sent back with every request, then they are stored as a cookie on the client. People get nervous when their passwords are written to files -- and such storage is not equivalent (from a security point of view) to the storage of an authentication token, because human user are on the (bad) habit of reusing their passwords for multiple systems, whereas authentication tokens are inherently server-specific.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.