Что такое IV по умолчанию при шифровании с помощью шифра aes_256_cbc?

Я сгенерировал случайный 256-битный симметричный ключ в файле, чтобы использовать его для шифрования некоторых данных с помощью командной строки OpenSSL, которые мне нужно позже расшифровать программно с помощью библиотеки OpenSSL. У меня нет успеха, и я думаю, что проблема может быть в векторе инициализации, который я использую (или не использую).

Я шифрую данные с помощью этой команды:

/usr/bin/openssl enc -aes-256-cbc -salt -in input_filename -out output_filename -pass file:keyfile

Я использую следующий вызов для инициализации расшифровки данных:

EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))

keyfile это vector<unsigned char> который содержит 32 байта ключа. Мой вопрос касается этого последнего параметра. Предполагается, что это будет вектор инициализации алгоритма шифрования. Я не указывал IV при шифровании, поэтому должно быть использовано какое-то значение по умолчанию.

Означает ли передача nullptr для этого параметра «использовать значение по умолчанию»? Является ли значение по умолчанию пустым и ничего не добавляется в первый блок шифра?

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

11

Решение

Что такое IV по умолчанию при шифровании с помощью шифра EVP_aes_256_cbc () [sic] …

Означает ли передача nullptr для этого параметра «использовать значение по умолчанию»? Является ли значение по умолчанию пустым и ничего не добавляется в первый блок шифра?

Здесь ничего нет. Вы должны предоставить это. Для полноты IV должен быть непредсказуемым.

Непредсказуемый немного отличается от обоих уникальный а также случайный. Например, SSLv3 использовал последний блок зашифрованного текста для IV следующего блока. это было уникальный, но это не было ни случайный ни Непредсказуемый, и это сделало SSLv3 уязвимым для выбранных атак открытым текстом.

Другие библиотеки делают хитрые вещи, например, предоставляют нулевой вектор (строку из 0). Злоумышленники благодарят их за это. Также см Почему использование неслучайного IV с режимом CBC является уязвимостью? на переполнение стека и Является ли AES в режиме CBC безопасным, если используется известный и / или фиксированный IV? на Crypto.SE.


/usr/bin/openssl enc -aes-256-cbc...

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

OpenSSL использует внутреннюю функцию создания гибридов / ключей, которая принимает пароль, получает ключ и iv. Это называется EVP_BytesToKey, и вы можете прочитать об этом на страницах руководства. Страницы руководства также говорят:

Если общий ключ и длина IV меньше длины дайджеста и используется MD5, тогда алгоритм деривации совместим с PKCS # 5 v1.5, в противном случае для получения дополнительных данных используется нестандартное расширение.

Есть много примеров EVP_BytesToKey как только вы знаете, что искать. Openssl пароль для ключа один в C. Как расшифровать файл в Java, зашифрованный командой openssl с использованием AES в одном на Яве.


EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))

Я не указывал IV при шифровании, поэтому должно быть использовано какое-то значение по умолчанию.

Проверьте ваши возвращаемые значения. Вызов должен был потерпеть неудачу где-нибудь на пути. Может быть, не в EVP_DecryptInit_ex, но наверняка раньше EVP_DecryptFinal,

Если это не сбои, пожалуйста, отправьте отчет об ошибке.

7

Другие решения

EVP_DecryptInit_ex интерфейс к примитиву расшифровки AES Это всего лишь часть того, что вам нужно для расшифровки формата шифрования OpenSSL. Формат шифрования OpenSSL плохо документирован, но вы можете работать с ним в обратном направлении из кода и некоторых документов. Ключ и IV вычисление объясняется в EVP_BytesToKey документация:

   The key and IV is derived by concatenating D_1, D_2, etc until enough
data is available for the key and IV. D_i is defined as:

D_i = HASH^count(D_(i-1) || data || salt)

where || denotes concatentaion, D_0 is empty, HASH is the digest
algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data) is
HASH(HASH(data)) and so on.

The initial bytes are used for the key and the subsequent bytes for the
IV.

«ХЭШ» здесь — это MD5. На практике это означает, что вы вычисляете хэши следующим образом:

Hash0 = ''
Hash1 = MD5(Hash0 + Password + Salt)
Hash2 = MD5(Hash1 + Password + Salt)
Hash3 = MD5(Hash2 + Password + Salt)
...

Затем вы извлекаете байты, необходимые для ключа, а затем вытягиваете байты, необходимые для IV. Для AES-128 это означает, что Hash1 — это ключ, а Hash2 — это IV. Для AES-256 ключ — это Hash1 + Hash2 (сцепленный, не добавленный), а Hash3 — это IV.

Вам нужно скинуть ведущий Salted___ заголовок, затем используйте соль для вычисления ключа и IV. Тогда вы будете иметь кусочки, чтобы накормить EVP_DecryptInit_ex,

Так как вы делаете это в C ++, вы, вероятно, можете просто копаться в enc код и использовать его повторно (после проверки его лицензии совместима с вашим использованием).

Обратите внимание, что OpenSSL IV генерируется случайным образом, так как это результат процесса хеширования со случайной солью. Безопасность первого блока не зависит от случайности как таковой; это просто требует, чтобы определенная пара IV + Key никогда не повторялась. Процесс OpenSSL гарантирует, что случайная соль никогда не повторяется.

Возможно, что использование MD5 таким образом запутывает ключ и IV таким образом, что происходит утечка информации, но я никогда не видел анализа, который бы утверждал это. Если вам нужно использовать формат OpenSSL, у меня не будет никаких колебаний по поводу его IV поколения. Большие проблемы с форматом OpenSSL состоят в том, что он быстро перебирает силу (4 раунда MD5 недостаточно для растяжения) и не требует какой-либо аутентификации.

5