0
$\begingroup$

We're building a stateless RESTful API that relies on the content of OAuth2 tokens to identify users and what they have access to. Users authenticate with other means and are given a token, which they then use to authenticate API requests for an hour or so till it expires.

Since we want it to be stateless, we can't use random tokens with a lookup table. The token basically consists of username + start timestamp + end timestamp. (The token is considered valid if it has a valid user and the current time is between the start and end timestamps.) We encrypt the token before sending it to the user and decrypt it each time we get it back in a request.

If we naively encrypt the token with AES in ECB mode, the ciphertexts for a given user's tokens end up very similar to one another, because the usernames encrypt to the same ciphertext every time, and I assume somebody who knew what they were doing could XOR a few tokens together and recover the key fairly easily.

If we encrypt them in CBC mode instead -- with a fixed IV, so we can decrypt them later -- I assume the attack is a little harder (maybe a lot harder? maybe not harder at all?), but the ciphertexts still end up very similar.

What we're currently doing to get around this is reverse the token (bytewise) before encrypting in CBC mode, so the highest-entropy bytes get encrypted first and feed into the rest of the chain, and there's no obvious similarity between ciphertexts, and at least we don't look stupid. But, as they say, anyone can design a cryptosystem they themselves can't break.

Questions, then:

  • Is this actually doing any good?
  • Is there a known best practice we should be following instead?
  • If there isn't a known best practice, are there any obvious improvements?

(Note: All of this is happening over SSL so we're not particularly worried about man-in-the-middle attacks etc. But we don't want to encourage any otherwise authorized users to try to forge tokens, either.)

$\endgroup$
1
  • $\begingroup$ A note: even with use of ECB mode, as long as you do not encipher (a derivative of) the key using itself, there is no way that knowledge of ciphertext and plaintext will allow an adversary to recover the key, or something that would allow to decipher or encipher some random thing. The best an adversary can do is recognize plaintext/ciphertext blocks that previously occurred, and recompose fake plaintexts by recomposing ciphertext blocks. A question: how is the key of your AES generated, stored (if it is across session), and used? That's a classical weak spot. $\endgroup$
    – fgrieu
    Commented Feb 9, 2014 at 18:15

1 Answer 1

1
$\begingroup$

It probably is doing some good, although there's probably
a simple attack, depending on how long your fields are.

You should use a MAC or authenticated encryption, depending on whether or not you
want to keep $\:$ username + start timestamp + end timestamp $\:$ confidential from someone
who gets access to a user's computer while that computer has a token from your site.

$\endgroup$
1
  • $\begingroup$ Thanks -- authentication was the conceptual piece I was missing. I've switched to GCM. $\endgroup$ Commented Feb 10, 2014 at 17:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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