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

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

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

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

Я точно знаю, что это зашифровано с помощью AES/Rijndael 128-бит ECB, ключ — 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, чтобы сделать обмен байтами.

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

решение1

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

АЕСработает с ключом, а не с паролем. Ключ 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 с ключом 524544525944455200000000000000000 дает 464c41473d44414953590000000000000 (используя шестнадцатеричное представление для представления последовательностей байтов). Это FLAG=DAISY\0\0\0\0\0\0.

Для таких небольших криптографических манипуляций мне нравится верхний уровень Python с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'

решение2

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

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

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

openssl — это вуду!

Связанный контент