Score:0

In AES-128-ECB, if byte 15 is over 128, the padding block changes value. What's the reason for this behavior?

um flag

For example, if we run this openssl command:

openssl aes-128-ecb -a -in <(echo -n "AAAAAAAAAAAAAAAA") -K "deadbeefdeadbeefdeadbeefdeadbeef"

The output in hex looks like:

block 1                          block 2
7a03acccf884d4ac38b7a2f3529806fa adfbc6ad78223f79cded6638d1d9802b

If I run it again and change the last byte, I get:

openssl aes-128-ecb -a -in <(echo -n "AAAAAAAAAAAAAAAa") -K "deadbeefdeadbeefdeadbeefdeadbeef"

block 1                         block 2
0c6b99d8659660bb763ca8a442948da4 adfbc6ad78223f79cded6638d1d9802b

Note the second block is identical. If we decrypt just that block, we get the expected PKCS7 padding of 16 (0x10) repeated (i.e. "10101010101010101010101010101010")

echo "adfbc6ad78223f79cded6638d1d9802b" | xxd -r -p | openssl aes-128-ecb -d -K "deadbeefdeadbeefdeadbeefdeadbeef" -nopad | xxd -p

# gives
10101010101010101010101010101010

However, if we replace the last byte with a character that's 128 or over, we get a different second block. (Note € is ASCII 128)

openssl aes-128-ecb -a -in <(echo -n "AAAAAAAAAAAAAAA€") -K "deadbeefdeadbeefdeadbeefdeadbeef" | base64 -d | xxd -p -c100

block 1                          block 2
2ec43df437eeed3a67a3390e53be7040 2999ee9243fefd95a9b3214cec97e13f

That second block decrypted is "82ac0e0e0e0e0e0e0e0e0e0e0e0e0e0e" which corresponds to 130, 172, and then 14 (i.e. 2 bytes of information and the rest padding).

I'm really confused about where those 2 bytes are coming from, and I can't seem to find any mention of this behavior when googling around.

Does anyone know why this happens?

Score:2
ng flag

(Note € is ASCII 128)

This is incorrect. Proper ASCII is a 7-bit encoding, there is no 128th element there. The Euro sign (€) is decimal 128 in some extended-ASCII encodings, most famously Windows-1252. However, your Linux system is very likely using UTF-8. There, the Euro sign will be encoded as three bytes 0xE282AC:

~$ echo -n "€" | xxd -p
e282ac

Thus your input is 18 bytes long, meaning two bytes "spill over" into the second block, which will then have a padding of 14 bytes of value 14 - ie 0x0E.

carleton avatar
um flag
That was my issue! thank you. When I feed the hex in via xxd the 2nd block matches. `echo "41414141414141414141414141414180" | xxd -r -p | openssl aes-128-ecb -K "deadbeefdeadbeefdeadbeefdeadbeef" | xxd -p -c 100`
carleton avatar
um flag
I originally came across this doing some crypto in Javascript and there is something truly terrible going on. There are 2 euro symbols that will render fine in my browser field: and €. One of them is the utf-8 valid one, the other I think is UTF-16, which if I try to copy paste into the URL bar which has I guess stricter encoding checks, it gives me the question mark block. Very strange! (edit: the first one doesn't show up on submit!)
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.