Opciones adecuadas para openssl con texto cifrado simple

Opciones adecuadas para openssl con texto cifrado simple

El fin de semana pasado hubo un desafío criptográfico donde el texto cifrado era el siguiente hexadecimal:

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

Estoy seguro de que esto está cifrado utilizando AES/Rijndael ECB de 128 bits, la clave es REDRYDER y ya se ha publicado una solución para confirmarlo. El texto sin formato es BANDERA=MARGARITA. Escribí un script PHP mcrypt simple que descifra esto sin salt o sin cadena IV y lo descifra correctamente. Sin embargo, cuando intenté usar openssl, no obtengo el texto sin formato:

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

Esto solo genera algunos datos binarios. También intenté pasar la entrada a través de dd conv=swab para realizar un intercambio de bytes.

¿Qué estoy haciendo mal?

Respuesta1

La opensslherramienta de línea de comandos es una demostración de la biblioteca OpenSSL. Tiene una interfaz bastante desordenada y documentación deficiente. No recomiendo usarlo para nada más que probar la biblioteca OpenSSL. (Sí, hay personas que administran CA con openssl. Temo por su cordura).

AESFunciona con una clave, no con una contraseña. Una clave AES-128 tiene exactamente 16 bytes.

La opción -kno acepta una clave como entrada, sino una contraseña. Esta contraseña tiene un hash para derivar una clave; el valor predeterminado es MD5 y se puede anular con la opción de línea de comando -md. Hasta donde puedo ver, esto no está documentado en el manual, solo tienes que leer la fuente ( apps/enc.c, llamar a EVP_BytesToKey). El resumen MD5 produce un valor de 16 bytes a partir de cualquier cadena, pero esto no es lo que se usó aquí. En este caso, la clave es en realidad REDRYDER\0\0\0\0\0\0\0\0donde \0hay bytes nulos.

La opción -Kte permite pasar una clave, en hexadecimal. Si pasa menos bytes que el tamaño de la clave, OpenSSL completa con bytes nulos. Entonces, para pasar la clave REDRYDER\0\0\0\0\0\0\0\0, puedes pasar $(echo REDRYDER | od -An -tx1 | tr -d ' ')cuál es 5245445259444552.

La operación de descifrado AES-128-ECB del bloque de texto cifrado FC89BFC2B05F1C2E64B8784392783AC9 con la clave 52454452594445520000000000000000 produce 464c41473d4441495359000000000000 (usando xadecimal para representar las secuencias de bytes). Eso es FLAG=DAISY\0\0\0\0\0\0.

Para pequeñas manipulaciones criptográficas como estas, me gusta el nivel superior de Python con elPycryptobiblioteca.

>>> 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)
'FLAG=DAISY\x00\x00\x00\x00\x00\x00'

Respuesta2

Esto funciona:

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

No entiendo la entrada para la opción -k, pero si convierte su clave de texto sin formato a hexadecimal (ordenamiento de bytes adecuado) y usa -K en su lugar, funciona.

openssl es vudú!

información relacionada