# How to break AES/CBC/PKCS5 when key and IV are reused?

I'm doing a code review for a crypto solution that reuses the same key with a constant IV. I want to demonstrate that this is not the right way to do things by figuring out the key and decrypting all of their test data.

• I know the same key is used.
• I know the same IV is used.
• Cipher is AES/CBC/PKCS5
• Plaintext is 16 bytes.
• Ciphertext is 32 bytes (PKCS5 padding?)
• I can put whatever plaintext I want through the system and then get that ciphertext.

What's the high-level pseudo code or process to break this system?

-
PKCS5? What the fuck? Why are you even using a padding scheme if the ciphertext is the exact same size as the block size? – orlp Nov 21 '13 at 17:09
Reused IV = (adaptive) chosen plaintext attack vulnerable. Padding a full block = stupid and wasteful. PKCS7 = correct padding for AES. – Richie Frame Nov 21 '13 at 19:16
The code supports larger plaintext sizes, so maybe that's the reason for PKCS7. – Heathkit7 Nov 21 '13 at 19:32
Richie - can you elaborate on the chosen plaintext attack? Because that's exactly what I'm trying to do. – Heathkit7 Nov 21 '13 at 19:46
It's not a password database, is it? Adobe did that, and look where it got them. – Ilmari Karonen Nov 22 '13 at 3:44

Well, there is no really good way; the encryption of the plaintext is $E_k( Plaintext \oplus IV)$ (followed by 16 bytes which are a deterministic function of the first ciphertext block). The AES function $E_k$ is designed to be totally unpredictable if you don't know the key, there's nothing to leverage there. The only thing that allows you to gain any advantage is that the encryption function itself is deterministic; that is, about the best you have available is:

• Make a guess as to what the plaintext might be

• Check to see if that ciphertext happens to match anything on your list

• Rinse and repeat

Not by any means an ideal solution; however it's the best option you have available.

Now, if the plaintext had been longer than 16 bytes, you could use the above procedure to confirm a guess on the first 16 bytes of the plaintext, and then work on the next 16 bytes -- with your specified parameters, that's not an option.

-
Thank you for this detailed comment. I tried to work through the Wikipedia article on IV to work out a known-plaintext attack. I really thought that was the path forward to breaking this. Is that an attack that works for other ciphers, but not AES? – Heathkit7 Nov 21 '13 at 19:44
@Heathkit7: well, no block cipher would be considered secure if it were vulnerable to a known plaintext attack; hence it's not specific to AES. Now, if you used 3DES, say, or Blowfish, then my last observation (that you can guess individual blocks) would be useful (because in that case, you could verify a guess which had the first 8 bytes correct, rather than having to get all 16 bytes correct at once) – poncho Nov 21 '13 at 19:46
Ahh, I think I missed the distinction between stream and block ciphers in that article. – Heathkit7 Nov 21 '13 at 20:19

If the last 16 bytes of the ciphertext are the padding, then you actually have the simple ECB (Electronic CodeBook) mode. ECB is secure as long as all your plaintexts are 1 block long and never repeat.

-
When I first saw the data, I thought they were in ECB mode because I saw several rows of identical ciphertext. That's how I figured out they were reusing the same IV (and key) every time. – Heathkit7 Nov 21 '13 at 19:34
+1 for noting the equivalence to ECB. Basically, the ways to attack this scheme are the same as you'd use to attack ECB (i.e. rely on the determinism to leak information if plaintext blocks are repeated). – Ilmari Karonen Nov 22 '13 at 3:41

You do not mention any authentication of the ciphertexts. If you could change the IV (which sounds highly unlikely) then you could make rather precise changes to the plaintext (as if it was a stream cipher).

Ideally from your point of view, there may be a padding oracle attack (which I don't understand and so won't describe here).

If you can change the first ciphertext block and figure out what padding scheme they are using, then you can cause decryption to output a plaintext that is longer than 16 bytes, in which the first 16 bytes are garbled and the rest of the output is chosen by you. If you can change both ciphertext blocks and learn what plaintexts those ciphertexts decrypt to and figure out what padding scheme they are using, then you can cause decryption to output a plaintext that is longer than 16 bytes, in which you have a tiny bit of control over the first 16 bytes of plaintext and the rest of the plaintext is chosen by you.

If you change the first ciphertext block and figure out what padding scheme they are using, and their unpadding is implemented in a way that will not reject when the final block decrypts to all-zero, then for each ciphertext there is a plaintext of less than 16 bytes that you can cause decryption to output.

-
+1 for mentioning the padding oracle attack – Maarten Bodewes Nov 24 '13 at 2:31