Signed session cookies. A good idea?


In an effort to increase performance, I was thinking of trying to eliminate a plain 'session cookie', but encrypt all the information in the cookie itself.

A very simple example:

userid= 12345
time=now()
signature = hmac('SHA1',userid + ":" + time, secret);

cookie = userid + ':' + time + ':' + signature;

The time would be used for a maximum expirytime, so cookies won't live on forever.

Now for the big question: is this a bad idea?

Am I better off using AES256 instead? In my case the data is not confidential, but it must not be changed under any circumstances.

EDIT

After some good critique and comments, I'd like to add this:

  • The 'secret' would be unique per-user and unpredictable (random string + user id ?)
  • The cookie will expire automatically (this is done based on the time value + a certain amount of seconds).
  • If a user changes their password, (or perhaps even logs out?) the secret should change.

A last note: I'm trying come up with solutions to decrease database load. This is only one of the solutions I'm investigating, but it's kind of my favourite. The main reason is that I don't have to look into other storage mechanism better suited for this kind of data (memcache, nosql) and it makes the web application a bit more 'stateless'.

10 years later edit

JWT is now a thing.


Answers:


A signed token is a good method for anything where you want to issue a token and then, when it is returned, be able to verify that you issued the token, without having to store any data on the server side. This is good for features like:

  • time-limited-account-login;
  • password-resetting;
  • anti-XSRF forms;
  • time-limited-form-submission (anti-spam).

It's not in itself a replacement for a session cookie, but if it can eliminate the need for any session storage at all that's probably a good thing, even if the performance difference isn't going to be huge.

HMAC is one reasonable way of generating a signed token. It's not going to be the fastest; you may be able to get away with a simple hash if you know about and can avoid extension attacks. I'll leave you to decide whether that's worth the risk for you.

I'm assuming that hmac() in whatever language it is you're using has been set up to use a suitable server-side secret key, without which you can't have a secure signed token. This secret must be strong and well-protected if you are to base your whole authentication system around it. If you have to change it, everyone gets logged out.

For login and password-resetting purposes you may want to add an extra factor to the token, a password generation number. You can re-use the salt of the hashed password in the database for this if you like. The idea is that when the user changes passwords it should invalidate any issued tokens (except for the cookie on the browser doing the password change, which gets replaced with a re-issued one). Otherwise, a user discovering their account has been compromised cannot lock other parties out.