Почему openssl AES дает другой результат, чем любой онлайн-инструмент, который я пробую? - PullRequest
0 голосов
/ 18 апреля 2020

Я пытаюсь зашифровать строку с помощью AES.

На своем Macbook я ввожу команду

echo -n "hello" | openssl enc -e -aes-128-cbc

и ввод ключа 123456.

Результат: U2FsdGVkX1+FBre1MZ1YDfgZRmRyt/hMogfMhYeiq8Q=

Однако, когда я тогда попробую любой инструмент онлайн-шифрования, я получу другой результат.

Например, на этом сайте закодировать-декодировать используя ту же схему шифрования, я получаю

NrjrStoGrmkLAvWaJuKtvg==

Почему разница? В какой конфигурации мне не хватает?

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Прежде всего: воспроизвести опубликованный зашифрованный текст NrjrStoGrmkLAvWaJuKtvg== на опубликованном веб-сайте для настройки по умолчанию AES-128-CB C и открытого текста hello, ключ 12345678 ( и не 123456, как указано) должны применяться.

Сайт использует PKCS7 заполнение. Ключ кодируется UTF8 и дополняется значениями 0x00 до необходимой длины (16 байтов для AES 128). В режиме CB C нулевой вектор применяется как IV. Поскольку это не описано (по крайней мере, я не нашел документацию), это может быть выведено только путем сравнения с эталонной реализацией или -website.

В OpenSSL ключ указывается с помощью -K параметр (в шестнадцатеричном формате), см. здесь . Если применяется IV, этот IV должен быть указан с опцией -iv (также в шестнадцатеричном формате). Таким образом, чтобы получить тот же результат, что и веб-сайт, вам нужно добавить в оператор OpenSSL:

-K 31323334353637380000000000000000 -iv 00000000000000000000000000000000

Если ключ не передан, OpenSSL запрашивает пароль, генерирует случайную 8-байтовую соль и получает ключ и IV из соли и пароля, используя функцию OpenSSL EVP_BytesToKey. По умолчанию используется дайджест SHA256 (начиная с версии 1.1.0 включительно, до MD5) и счетчик итераций 1. Выходной формат - кодировка ASCII Salted__, за которой следуют 8-байтовая соль и фактический зашифрованный текст, все Base64 закодировано. Поэтому зашифрованный текст всегда начинается с U2FsdGVkX1. Поскольку соль определяется случайным образом для каждого шифрования, каждый раз возникают разные ключи и IV и, следовательно, разные шифротексты. Ключ и IV могут отображаться с опцией -p.

С паролем 123456 (как отправлено) и дайджестом MD5 отправленный зашифрованный текст OpenSSL U2FsdGVkX1+FBre1MZ1YDfgZRmRyt/hMogfMhYeiq8Q= может быть расшифрован до открытого текста hello. Опция -p также может использоваться для дешифрования и показывает:

Key: F1A16DEEFFEE4AB705BB72C21C1F1CA2 
IV:  000A7A05E99BF90C025EFE40B534E836 

И наоборот, этот ключ и IV могут использоваться для непосредственного шифрования открытого текста hello, что приводит к зашифрованному тексту F819466472B7F84CA207CC8587A2ABC4. Если зашифрованный зашифрованный текст OpenSSL U2FsdGVkX1+FBre1MZ1YDfgZRmRyt/hMogfMhYeiq8Q= декодируется с помощью Base64 и первые 16 байтов (префикс и соль) отбрасываются, то результат того же зашифрованного текста, как и ожидалось.

Следует отметить, что использование ключа, используемое OpenSSL, не очень безопасно, здесь . Начиная с версии 1.1.1, OpenSSL поддерживает PBKDF2, но это должно быть явно указано.

1 голос
/ 18 апреля 2020

Я не могу воспроизвести ни один из ваших результатов (я не на Ма c). Вероятно, проблема связана с тем, что CB C является блочным шифром, что означает, что для каждого цикла шифрования требуется фиксированная длина блоков в 16 байтов (в отличие от потоковых шифров). Когда у вас есть менее 16 байтов данных, он будет использовать заполнение.

AES-CBC mode

Почему разница? Стандарт AES не определяет (.. Я знаю, это не очень полезно для нас) какой тип заполнения должен быть использован, так что он может отличаться в реализации между PKCS # 5 или PKCS # 7.

В моем случае мне даже намекали использовать это вместо выбранной вами операции *** WARNING : deprecated key derivation used. Using -iter or -pbkdf2 would be better. опция -pbkdf2 в openssl соответствует PKCS # 5. На самом деле у нас нет информации о том, какую библиотеку использует онлайн-инструмент для той же операции. Что касается результатов:

U2FsdGVkX1+FBre1MZ1YDfgZRmRyt/hMogfMhYeiq8Q= and 
NrjrStoGrmkLAvWaJuKtvg==

Base64 декодируют до следующего, соответственно:

Salted__1XFdrL̅
6Ji&⭾

Итак, из этого, вы можете видеть, что вывод шифрования openssl также использует соль, но даже тогда содержимое совершенно другое.

Какая конфигурация мне не хватает? Хотя, вы можете попробовать следующее:

 openssl enc -e -aes-128-cbc -pbkdf2 -nosalt

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

Вопрос в том, как вы собираетесь использовать схему шифрования в будущем - до тех пор, пока вы Если вы используете openssl последовательно, вы можете быть уверены, что он будет работать, хотя быстрый поиск в Google показал, что разные версии могут изменить и даже повлиять на это, поэтому я, вероятно, поэтому не могу расшифровать данные, представленные в OpenSSL 1.1. 1 11 сентября 2018 года. Также здесь есть статья с некоторыми хорошими примерами и пояснениями.

...