Can You Trust AES Encryption?

Prof Bill Buchanan OBE FRSE
3 min readJul 8, 2023

In this article, I will not break the AES method (as it has yet to be broken), but breach its integrity. This is because some modes of AES are not good at handling the integrity of the message. The fast stream cipher modes, such as with CTR, are especially prone to this lack of integrity checking, as it is easy to pick off the characters to target.

As a magic trick, I will take the encrypted message of:

Pay Bob 1 dollar

and then flip a few bits to give the ciphertext for:

Pay Bob 2 dollar

In ASCII, a ‘1’ is 0110001, and a ‘2’ is 0110010, and so all I have to do, is to find the place of the character I want to flip in the ciphertext, and then flip the two least significant bits.

First, I will encrypt the message using AES CTR mode — a fast stream cipher mode with AES — and use a passphrase of “Bob123”. The encryption key will be generated using PBKDF2:

$ echo "Pay Bob 1 dollar" | openssl enc -k bob123 -e -aes-128-ctr -pbkdf2 >ciphertext

The ciphertext will be in a binary form:

$ cat ciphertext
Salted__?T????i??k=e??n??.3?%

We can then use xxd to convert this binary format into a ciphertext so that we can edit the ciphertext:

$ xxd ciphertext > data
$ cat data
00000000: 5361 6c74 6564 5f5f f354 1385 819d f1a3 Salted__.T......
00000010: 69fa 816b 3d65 80ed 136e a405 f02e 3307 i..k=e...n....3.
00000020: e6

AES CTR is a stream mode, so it is easy to find all of the characters in the cipher, as they map straight to their position in the plaintext. Now, we ignore that last byte (e6) and count back the number of characters to the ciphertext of ‘1’. In this case, it is eight characters from the end, so let’s use change the ciphertext to:

(base) billbuchanan@ASecuritySite ~ % cat data
00000000: 5361 6c74 6564 5f5f f354 1385 819d f1a3 Salted__.T......
00000010: 69fa 816b 3d65 80ed 106e a405 f02e 3307 i..k=e...n....3.
00000020: e6

In this case, I have changed “136e” to “106e”, and only flipped two bits (from 0010011 to 0010000, and which should change a ‘1’ to a ‘2’ ). Now we will convert the cipher back into binary, and decrypt:

% xxd -r data > ciphertext
% cat ciphertext
Salted__?T????i??k=e??n??.3?%
% cat ciphertext | openssl enc -k bob123 -d -aes-128-ctr -pbkdf2
Pay Bob 2 dollar

And magically, we have converted one dollar into two!!!!

Why does this happen? Well, the integrity checking in OpenSSL is not very good, and it struggles to detect whether bits have been flipped in the cipher.

Here is the demo:

Overall, CTR and GCM are two of the fastest and most widely used modes in AES. Their great advantage is that they convert the block mode into a stream cipher (and thus do not need padding and can be processed in parallel). They are only beaten for performance by ECB, and which has serious weaknesses (as it has no nonce input):

If you are interested in the performance of AES modes, try here:

--

--

Prof Bill Buchanan OBE FRSE

Professor of Cryptography. Serial innovator. Believer in fairness, justice & freedom. Based in Edinburgh. Old World Breaker. New World Creator. Building trust.