AES busting¶
AES is a symmetric key, block cipher algorithm. It is used in many common Internet protocols and operating system services, including TLS, IPsec, and file-level or full-disk encryption. Given its ubiquity, it is an important cipher to know how to use, and the principles of (in)correct use of AES transfer easily to (in)correct use of other ciphers.
Even though AES is a block cipher, it (like many other block ciphers) can be used in a way that makes it behave like a stream cipher.
AES processes blocks of 128 bits using a secret key of 128, 192, or 256 bits, with the 128-bit key being the most common because it makes encryption slightly faster and because the difference between 128- and 256-bit security is meaningless for most applications.
AES modes¶
Mode |
Notes |
|---|---|
Electronic Code Book (AES-ECB) |
Each 16-byte block of plaintext is encrypted independently. |
Cipher Block Chaining (AES-CBC) |
Each plaintext block gets XOR-ed with the previous ciphertext |
Cipher FeedBack (AES-CFB) |
The keystream is obtained by encrypting the last ciphertext |
Output FeedBack (AES-OFB) |
The keystream is obtained by recursively encrypting the |
Counter (AES-CTR) |
The keystream is generated by encrypting a sequence of counter |
Galois Counter Mode (AES-GCM) |
A combination of Counter mode (CTR) and Authentication. |
Encrypt-then-authenticate- |
Another method for Authenticated Encryption with AES. |
Pros and cons¶
Of these, GCM gives the strongest guarantees.
Name |
Pros |
Cons |
|---|---|---|
ECB |
Simplest. |
Weakest cipher |
CBC |
Each ciphertext is different |
Padding needed. |
CFB |
A stream cipher accepts data of any |
Each ciphertext relies on the other to be decrypted |
OFB |
A stream cipher accepts data of any |
The correct IV is needed to decrypt the whole thing |
CTR |
A stream cipher accepts data of any |
Corrupted data cannot be recovered. |
GCM |
Guarantees integrity. |
Complex implementation. |
EAX |
Detects unauthorised modifications. |
Slower than GCM. |
ECB¶
The most basic encryption mode is the electronic codebook (ECB) mode. The message is divided into blocks and each block is encrypted separately. The problem is that if the same plain text is submitted more than once, the same ciphertext is always produced. This gives attackers a place to begin analysing the cipher to attempt to derive the key. ECB is using the cipher exactly as it is described without improving its security.
There is no good reason to use ECB over CBC, if both ends of the communication can support CBC.
CBC¶
When using cipher block chaining (CBC) mode, each block of plaintext is XOR’d with the previous ciphertext block before being encrypted. This means there is more randomness in the final ciphertext. This is much more secure than electronic codebook mode.

The only issue with CBC is the first block. There is no preceding block of ciphertext to XOR the first plaintext block with. It is common to add an initial vector (IV) to the first block so that it has something to be XOR’d with. The initial vector is a pseudorandom number, much like the cipher key. Usually, an IV is only used once, a nonce (Number Only used Once).
The decryption process in CBC mode is done as:

where \(nb\) is the number of blocks.
Bit-flipping attack¶
If the position of the target byte is known, then the corresponding ciphertext position in the previous ciphertext block can be modified. For example, if a byte in the ciphertext \(C_{i-1}\) is modified, then the corresponding byte of \(P_i\) is changed, since \(C_{i-1}\) only affects the plaintext \(P_i\) by \(\oplus\).

A ciphertext byte of \(C_2\) is modified: this changes the corresponding byte in the next plaintext block \(P_3\), and turns the whole block \(P_2\), at the same index as the modified ciphertext, into garbage.
An \(\text{IV}\) byte is modified: This affects only the corresponding byte in the first plaintext \(P_1\). If the target plaintext is in the first block, this will not leave a trace.
Padding oracle attack¶
A padding oracle is a system that behaves differently depending on whether the padding in a CBC-encrypted ciphertext is valid. It can be seen as a black box or an API that returns either a success or an error value. A padding oracle can be found in a service on a remote host sending error messages when it receives malformed ciphertexts. The preferred method of padding block ciphertexts is PKCS7. In PKCS7, the value of each padded byte is the same as the number of bytes being added.
Given a padding oracle, padding oracle attacks record which inputs have a valid padding and which do not, and exploit this information to decrypt chosen ciphertext values.
Assume a CBC-encrypted ciphertext has been intercepted, and a server can be reached that accepts any ciphertext and indicates whether it decrypts to plaintext with valid padding. The server is used as oracle.
In CBC decryption, each ciphertext is passed through the cipher, then XORed with the previous ciphertext block to give the plaintext. The attack works by calculating the “intermediate state” of the decryption for each ciphertext. This is the state of a ciphertext block after being decrypted by the block cipher but before being XORed with the previous ciphertext block.

\(C_1\) is known already, as it is just part of the intercepted ciphertext, so if \(I_2\) is found then \(P_2\) can be trivially found and the ciphertext decrypted.

Pick a random block \(C_1\) and vary its last byte until the padding oracle accepts the ciphertext as valid. Usually, in a valid ciphertext, \(C_1[15] ⊕ X[15]\) = 01, so \(X[15]\) will be found after trying around 128 values of \(C_1[15]\).
Find the value \(X[14]\) by setting \(C_1[15]\) to \(X[15] ⊕ 02\) and searching for the \(C_1[14]\) that gives correct padding. When the oracle accepts the ciphertext as valid, it means \(C_1[14]\) has been found such that \(C_1[14] ⊕ X[14] = 02\).
Repeat steps 1 and 2 for all 16 bytes.
In the wilderness (real digital world), implementing a padding oracle attack is a bit more complicated than that,
because one has
to deal with wrong guesses at step 1.
A ciphertext may have valid padding not because \(P_2\) ends with a single 01 but because it ends with two 02 bytes or
three 03 bytes. But that’s easily managed by testing the validity of ciphertexts where more bytes are modified.
CTR¶
In CTR mode, encryption XORs the plaintext and the stream taken from “encrypting” the nonce, N, and counter, Ctr.
Decryption is the same, so only the encryption algorithm is needed for both
encryption and decryption.
RootMe challenges¶
Security¶
Never reuse key and IV pairs. Reusing a key and IV pair in CBC produces predictable output for predictable headers. Boilerplate or structured parts of a message, easily overlooked, become a liability; adversaries can use predictable ciphertext to learn about the keys. Reusing a key and IV in counter mode is even worse. XORing a known plaintext against its ciphertext yields as many bytes of keystream as that plaintext is long, and those bytes decrypt the same stretch of anything else sent under the same key and counter.
Keys must be drawn from good sources of randomness. The random package is a pseudo-random number generator and not
even a good one at that. Pseudo-random generators are deterministic, generating numbers that appear random to humans,
but are always the same given a known seed value.
Padding is where much of this goes wrong, and modes like AES-GCM or EAX avoid that ground.