Last weekend there was a cryptographic challenge where the ciphertext was the following hex:

FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9

I know for sure that this is encrypted using AES/Rijndael 128-bit ECB, the key is REDRYDER and a solution for this has already been posted to confirm this. The plain text is FLAG=DAISY. I wrote a simple PHP mcrypt script that decrypts this with no salt or no IV string and it decrypts properly. However, when I tried to use openssl, I don't get the plain text:

echo "0: FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9" | xxd -r | openssl aes-128-ecb -d -k REDRYDER -nosalt -nopad ; echo

This just outputs some binary data. I also tried passing the input through dd conv=swab to do a byte swap.

What am I doing wrong?


The openssl command line tool is a demo of the OpenSSL library. It has a pretty haphazard interface and poor documentation. I don't recommend using it for anything other than testing the OpenSSL library. (Yes, there are people who manage CAs with openssl. I fear for their sanity.)

AES operates with a key, not with a password. An AES-128 key is exactly 16 bytes.

The option -k doesn't take a key as input, it takes a password. This password is hashed to derive a key; the default is MD5 and it can be overridden with command line option -md. This isn't documented in the manual as far as I can see, you just have to read the source (apps/enc.c, call to EVP_BytesToKey). The MD5 digest produces a 16-byte value from any string, but this isn't what was used here. In this case, the key is actually REDRYDER\0\0\0\0\0\0\0\0 where the \0 are null bytes.

The option -K lets you pass a key, in hexadecimal. If you pass fewer bytes than the key size, OpenSSL completes with null bytes. So to pass the key REDRYDER\0\0\0\0\0\0\0\0, you can pass $(echo REDRYDER | od -An -tx1 | tr -d ' ') which is 5245445259444552.

The AES-128-ECB decryption operation of the ciphertext block FC89BFC2B05F1C2E64B8784392783AC9 with the key 52454452594445520000000000000000 yields 464c41473d4441495359000000000000 (using hexadecimal to represent the byte sequences). That's FLAG=DAISY\0\0\0\0\0\0.

For little cryptographic manipulations like these, I like the Python toplevel with the Pycrypto library.

>>> from binascii import hexlify, unhexlify
>>> from Crypto.Cipher import AES
>>> ciphertext = unhexlify('FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9'.replace(' ', ''))
>>> key = 'REDRYDER'.ljust(16, '\0')
>>> AES.new(key, AES.MODE_ECB).decrypt(ciphertext)

This works:

echo '0: FC89BFC2B05F1C2E64B8784392783AC9' | xxd -r | openssl enc -aes-128-ecb -d -nopad -nosalt -K 5245445259444552

I don't understand the input for the -k option, but if you convert your plain text key to hex (proper byte ordering) and use -K instead, it works.

openssl is voodoo!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.