I'm learning more about security and in my search also using Google Search I found the following question and answer on Stack Overflow:


So, to set it up, you'd create a server key k. Then, you'd create the cookie as follows:

keyhmac = HMAC(user name + expiration time, k)
encrypted = ENCRYPT(data, keyhmac)
hmacenc = HMAC(user name + expiration time + data + session identifier, keyhmac)
cookie = user name + expiration time + encrypted + hmacenc;

Then, you can decrypt it later by using the reverse process. The HMAC verifies that it was not tampered with outside your server (assuming that k is really secret)...

The fact that it includes a session identifier (SSL is best, but IP can possibly serve) means that it's immune to replay attacks or hijacking attacks.

I don't see how this is secure in any way? If I send the server the same cookie it will accept it. Yes, he talks about using the IP address as a session identifier, but that has its own problems. Besides that, I can easily store the IP address per session id on the server without this whole encryption scheme and get exactly the same level of security, for example, based on IP address? Or am I missing something?

1 Answer 1


What this answer is about is client-side storage.

The first premise is that all of this occurs in a SSL session, so this won't be intercepted by third parties. The remaining attacker, if any, is the user himself. In particular, only the actual user can send back the cookie value to the server.

Then the server wants to manage sessions, i.e. consider successive requests from the same client to be part of a whole "story". This implies that the server must remember session information from one request to the next.

Server-side memory implies two main issues:

  • The amount of storage on the server can grow quite high. Indeed, successive requests from a given client can occur with a rather large delay in-between (minutes, even hours or more). Also, a given client may stop sending requests altogether, and the server won't be warned about it. So on a busy server, we are talking about saving tens of thousands or more of "session information" objects. This can translate to a non-negligible number of megabytes of RAM.

  • If the server is multi-frontends, the user session information has to be shared between the frontends, which implies some extra communication, often with a shared database, which in turn can imply performance issues (a database is not as fast as pure local RAM).

So it would be neat if the user session information could be stored on the client himself. This is what this cookie+encryption+MAC scheme is about. The server packs what it wants to remember about a user session into a blob which is sent to the client; it is then up to the client to send it back with the next request. The server does not store anything on its side. This scales nicely to millions of users and dozens of frontends, since the server does not have to remember anything. It implies, however, its own challenges:

  • Since the data is stored on the client, the client may inspect it, which is not necessarily a good thing. Encryption solves that.
  • Since the data is stored on the client, the client may modify it, which is not necessarily a good thing. MAC solves that.
  • Since the server remembers nothing, it cannot prevent replay attacks where the client sends an old cookie value again. Including a date (under the protection of the MAC) mitigates this problem.
  • Cookie size is traditionally limited to about 4 kilobytes, so the server won't be able to make the client store much more data than that (well, the server could send several cookies, but reassembly becomes hard, especially if you want to do it securely).

The user name, SSL session identifier, or IP address, is just a non-secret identifier which is meant to prevent different users from swapping their cookies, voluntarily or not. For that matter, IP address is not a good identifier, because several users may share the same IP (in case of NAT or use of a Web proxy) and a given user's IP address may change (dynamic IP are not uncommon).

Now the specific scheme explained in the SO answer can be questionable; e.g. it applies the MAC on the cleartext data, not on the encrypted data, which is known to have potential issues: this is known as "encrypt-and-MAC". The potential problems can be avoided, but this requires some extra care in the implementation, so "encrypt-then-MAC" should be preferred. The reuse of the same key for the encryption and the MAC is also, generically speaking, a bad move; though it seems safe enough when the MAC is HMAC and the encryption uses some block cipher, we really prefer it when the two keys are somehow isolated from each other. A modern and more obviously secure way to do encryption and MAC would be to use one of the encryption modes which have been designed to do exactly that, e.g. GCM or EAX.

The idea is still sound (as long as all this occurs under the protection of SSL). The main remaining issue is dealing with replay attacks, which, depending on the application, may or may not be serious; the inclusion of the date in the cookie data allows the server to enforce an explicit expiration strategy to control this issue.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .