3
$\begingroup$

The company I work for needs to develop a simple system where, for each client, we encrypt a token on our server, which is then transmitted to the client. The decryption is performed by the server itself when the client transmits the token (thus the only machine that performs crypto is the server).

The token is for an external service, so integrity checking is not an issue.

I wrote code that encrypts these tokens using AES/CBC, using the same key and a unique IV; I am not aware of any practical attacks against AES, even with an arbitrarily large number of known ciphertexts.

My colleague insists that an adversary could break this (i.e. get the key and decrypt stuff) after collecting a (possibly large) amount of ciphertexts; thus, he argues that we should have one key per client on the server.

Who is correct?

$\endgroup$
  • $\begingroup$ Unless the tokens fit AES block size, you will have to use some mode of operation (e.g., CBC, CTR, GCM, etc). Is this your case? Your question depends a lot on this. $\endgroup$ – cygnusv Dec 10 '15 at 10:58
  • $\begingroup$ Sorry, I forgot to mention it - I'm using CBC, with a per-client IV. $\endgroup$ – Solal Pirelli Dec 10 '15 at 11:16
  • $\begingroup$ crypto.stackexchange.com/questions/10505/…, and security.stackexchange.com/questions/21371/… are relevant $\endgroup$ – cygnusv Dec 10 '15 at 11:21
  • 1
    $\begingroup$ How do you issue the per-client IV? $\endgroup$ – Simon Johnson Dec 10 '15 at 13:58
  • $\begingroup$ @SimonJohnson Java's SecureRandom. $\endgroup$ – Solal Pirelli Dec 10 '15 at 15:46
2
$\begingroup$

Now, on to your question.
But, since reusing the IV with the same key is something that you should never, ever, ever do, I'm going to assume that instead, you are generating a new random IV for each encryption, but using the same global encryption key.

The answer really depends on what your colleague means when he says break. There are academic breaks and there are practical breaks.

Your colleague is correct if we are referring to academic breaks. Assuming you are generating good, random IVs for each encryption, after capturing $2^{64}$ ciphertexts, we can expect to have had one duplicate IV (this comes from the birthday problem). Given the two ciphertexts that have duplicate IVs, the attacker can distinguish whether or not the two ciphertexts encrypt the same plaintext. Or even more accurately, the attacker can determine the number of blocks starting from the beginning that are the same. Once one block is different, however, the attacker cannot distinguish any further. That is an academic break. Capturing $2^{64}$ ciphertexts would be a very noisy attack and would require lots of disk space to store. But is not outside the realm of possibility.

That said, I don't see any way an attacker could feasibly break the key or a plaintext only given access to a huge (but practical) number of ciphertexts.

A better design
What would probably be a better design would be to generate a new, random key and IV for every encryption. Encrypt the plaintext with those (and use HMAC or an authenticated encryption mode). On the server you should have an asymmetric key pair (for example, an RSA key pair). Encrypt that random symmetric key using the public (RSA) key. Send the ciphertext and the encrypted symmetric key to the client.

When the client sends this back, you would decrypt the symmetric key using your private (RSA) key. Then decrypt the ciphertext with that key and check the HMAC or authentication tag.

My final suggestion is to hire somebody very knowledgable in this area to review your design and implementation (or even to help out with the design process) so you are not putting your customers at risk. I doubt it would cost very much.

$\endgroup$
  • $\begingroup$ Thanks for the answer. I wasn't clear enough in my question, so I clarified it; integrity checking is not an issue, and the IV is unique per request (from the app's point of view, two different requests = two different clients even if they end up being the same user). $\endgroup$ – Solal Pirelli Dec 10 '15 at 15:51
  • 2
    $\begingroup$ It's a mighty bold claim to suggest integrity checking is not an issue.Very often it turns out to be a very serious issue. The system may well be open to all sorts of chosen cipher-text attacks. $\endgroup$ – Simon Johnson Dec 10 '15 at 16:00
  • 1
    $\begingroup$ @SolalPirelli that is good that you are using unique IVs every time. There may be cases where integrity checking is not a real security issue. You better be very, very sure, however. And, you better be very, very sure that some new feature to your product doesn't make it an issue in the future. I personally wouldn't risk it and would add the integrity check. $\endgroup$ – mikeazo Dec 10 '15 at 16:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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