Правильные параметры для openssl с простым зашифрованным текстом

В минувшие выходные был криптографический вызов, где зашифрованный текст был следующим шестнадцатеричным:

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

Я точно знаю, что это зашифровано с использованием 128-битного ECB AES / Rijndael, ключ REDRYDER, и решение для этого уже было опубликовано для подтверждения этого. Обычный текст – FLAG = DAISY. Я написал простой скрипт PHP mcrypt, который расшифровывает это без соли или нет строки IV, и он дешифрует правильно. Однако, когда я пытался использовать openssl, я не получаю простой текст:

 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 

Это просто выводит некоторые двоичные данные. Я также попытался передать вход через dd conv = swab, чтобы сделать байтовый обмен.

Что я делаю не так?

Инструмент командной строки openssl представляет собой демонстрацию библиотеки OpenSSL. Он имеет довольно бессистемный интерфейс и плохую документацию. Я не рекомендую использовать его ни для чего, кроме тестирования библиотеки OpenSSL. (Да, есть люди, которые управляют ЦС с помощью openssl . Я боюсь за их здравомыслие.)

AES работает с ключом, а не с паролем. Ключ AES-128 составляет ровно 16 байт.

Опция -k не принимает ключ в качестве входа, он принимает пароль. Этот пароль хэширован для получения ключа; по умолчанию MD5, и его можно переопределить с помощью опции командной строки -md . Это не документировано в руководстве, насколько я вижу, вам просто нужно прочитать источник ( apps/enc.c , вызвать EVP_BytesToKey ). В дайджесте MD5 получается 16-байтовое значение из любой строки, но это не то, что было использовано здесь. В этом случае ключ на самом деле является REDRYDER\0\0\0\0\0\0\0\0 где \0 – пустые байты.

Опция -K позволяет передать ключ в шестнадцатеричном формате. Если вы пропускаете меньшее количество байтов, чем размер ключа, OpenSSL завершается нулевыми байтами. Итак, чтобы передать ключ REDRYDER\0\0\0\0\0\0\0\0 , вы можете передать $(echo REDRYDER | od -An -tx1 | tr -d ' ') который равен 5245445259444552 .

Операция дешифрования AES-128-ECB блока шифрования FC89BFC2B05F1C2E64B8784392783AC9 с ключом 52454452594445520000000000000000 дает 464c41473d4441495359000000000000 (с использованием шестнадцатеричных для представления последовательностей байтов). Это FLAG=DAISY\0\0\0\0\0\0 .

Для небольших криптографических манипуляций, подобных этим, мне нравится Python toplevel с библиотекой Pycrypto .

 >>> 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' 

Это работает:

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

Я не понимаю вход для параметра -k, но если вы преобразуете свой обычный текстовый ключ в hex (правильный порядок байтов) и вместо этого используете -K, он работает.

openssl – это вуду!