# 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?

• Reused IV = (adaptive) chosen plaintext attack vulnerable. Padding a full block = stupid and wasteful. PKCS7 = correct padding for AES. Nov 21, 2013 at 19:16
• The code supports larger plaintext sizes, so maybe that's the reason for PKCS7. Nov 21, 2013 at 19:32
• Richie - can you elaborate on the chosen plaintext attack? Because that's exactly what I'm trying to do. Nov 21, 2013 at 19:46
• It's not a password database, is it? Adobe did that, and look where it got them. Nov 22, 2013 at 3:44
• Now you seem to have three distinct good answers, good luck with that :P. Oh, note my Q/A on PKCS#5 vs PKCS#7 padding (you seem to be using Java, which uses "PKCS5Padding" instead of "PKCS7Padding"). Nov 24, 2013 at 2:32

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? Nov 21, 2013 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) Nov 21, 2013 at 19:46
• Ahh, I think I missed the distinction between stream and block ciphers in that article. Nov 21, 2013 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. Nov 21, 2013 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). Nov 22, 2013 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.