3

I am developing on a platform where my only encryption option uses AES ECB. The encryption is used to protect parameters that the user can set, and so it susceptible to a chosen plaintext attack. It's not a cookie, but similar; the user enters credentials, which with other data is sent to the server for authentication and authorisation.

What steps can I take to make the chosen plaintext attack impractical?

Specifically, my current proposed mitigation is to add random "fill" before and after my meaningful content. The encrypted blob will look roughly the same length, but the place where the ciphertext from the chosen plaintext appears will be different for each call. At this point the communications are low volume, so I am less worried about the efficiency, size or processing time of the data. Is this an effective mitigation?

Alternately I could consider randomising the order of the fields (the plaintext is JSON). That's a bit harder to implement. Would this make the attack impractical?

I have read and think I understand this great question and answer.

Tony
  • 178
  • 4
  • What platform only supports ECB? (If such a platform exists, then that is a sign that the crypto framework absolutely must not be trusted) – tylerl Jan 18 '16 at 05:01
  • [Metatrader](http://www.metaquotes.net/en/metatrader4). You might be right, but it's the only pony I have to ride. An alternative view is that this results in using the underling .NET framework, but they were lazy and didn't want to pass on all the options. In that case, the implementation is as good as AES ECB on .NET. That's an optimistic guess from me though. – Tony Jan 18 '16 at 06:10

1 Answers1

2

The simplest way of dealing with this I can think of is to more or less implement CBC mode yourself. All it requires is for you to be sure of the block size used:

  • Build a random (and unique) IV of the same size as the AES block size (128 bits).
  • Encrypt that block and store the result (let's call it A)
  • Build a chain of 128-bits blocks containing your actual message (add padding as needed).
  • For each block in that chain, XOR it with the content of the buffer A and encrypt it individually. Store the result in your output buffer and replace the content of the A buffer with it as well.

In order to decypher the data, you decrypt the first 128-bit block and store the result in a 128-bit buffer. You then take each 128-bit block thereafter, decrypt it, XOR the result with the content of buffer A, store the result both in your output buffer and in A and move to teh next block.

You then remove the pad and you're done.

Edit: One word of warning:

The best way would be to use a standard library instead of toying with code like this.

By doing what I suggested, you're running a rather severe risk of adding some vulnerability to your implementation: although I fully understand your need to work with specific limitations, you need to be aware of the fact that you are quite likely to end up with code that is vulnerable to some kind of attack (although it might be more resilient than the initial implementation).

Furthermore, if you rely on code that use ECB mode, it means that the author of that code had no understanding of modern cryptography and therefore probably contains other basic errors.

Stephane
  • 18,557
  • 3
  • 61
  • 70
  • Thanks. Ideally I'd like it to be compatible with a proper AES-CBC instance running on the server (I'm currently using Python's Crypto library, which handles the ECB stuff easily). Is it as easy as you describe to produce genuine AES-CBC? I like the idea, just want some certainty before I commit to developing it – Tony Jan 18 '16 at 10:51
  • 2
    Yes, using CBC using an ECB routine internally is as easy as I described (if it's really ECB: if there is any diffuser, even a broken one, you're toast). But in the end, if there is a compatibility issue, the fact is that you can't have your cake and eat it too: if your crypto library is broken in a way that will make the result incompatible "standard" CBC, you will need to chose whether you want compatibility or stick to your broken code. – Stephane Jan 18 '16 at 13:53
  • 2
    Make sure you test your home-rolled crypto against an established implementation to make sure the outputs are exactly the same. – sethmlarson Jan 18 '16 at 14:11
  • 1
    Thanks, I'm accepting this answer. It's not the answer I asked for but it's the one I needed. – Tony Jan 19 '16 at 09:52