- Ключ и IV получены из заданного вами пароля с использованием специфического для OpenSSL алгоритма, которым команда OpenSSL не гордится. Они сохраняют его для обеспечения обратной совместимости, но рекомендуют использовать лучшие функции получения ключей на основе паролей, такие как PKCS PBKDF2.
Алгоритм получения ключей OpenSSL находится в функции EVP_BytesToKey(3).
Ключ:
Ключ -K фактический ключ, который нужно использовать: он должен быть представлен в виде строки, состоящей только из шестнадцатеричных цифр.
IV:
В криптографии вектор инициализации (IV) или начальная переменная (SV) [1] является входом фиксированного размера для криптографического примитива, который обычно должен быть случайным или псевдослучайным.
Таким образом, IV - это дополнительный вход, используемый для шифрования файла. Это не ключ (я думаю, это просто терминология).
2 Соль - это дополнительный (префикс) к указанному вами ключу. (см. Википедия. Это делает невозможным использование радужных таблиц или предварительно вычисленных хеш-таблиц для вашего ключа. Соль обычно хранится в незашифрованном виде.
3 Вывод будет двоичным и, скорее всего, будет содержать непечатаемые символы. Ваш эмулятор терминала будет пытаться отобразить эти байтовые значения как печатные символы в кодировке и шрифте по умолчанию, но они, вероятно, будут выглядеть как "мусорный текст" и не будут безопасны для копирования / вставки, FTP или электронной почты.
4 Чтобы расшифровать зашифрованный текст, вам нужен ключ и IV. Если у вас нет ни одного, ни обоих из них, а те, которые вы пропустили, были получены из пароля, то, если у вас есть пароль, вы можете восстановить его недостающий ключ и / или IV из пароля. Соль вам не нужна, потому что она у вас уже есть; это предварительно прикреплено к началу зашифрованного текста. Соль на самом деле не секрет, это просто способ помешать предварительно вычисленным хеш-таблицам и радужным таблицам.
5 Как определено в EVP_BytesToKey(3), если вы используете пароль "1" и --nosalt
, первые 16 байт вашего ключа будут:
md5( D_0 || password || salt)
(обратите внимание, что в этом контексте ||
означает объединение, а не логическое or
)
что эквивалентно
md5 ( `null` || "1" || `null`)
что эквивалентно
md5("1")
Который оказывается
0xc4ca4238a0b923820dcc509a6f75849b
Это значение называется страницей D_1
.
Оставшиеся необходимые байты ключа и IV генерируются следующим образом:
md5( D_1 || password || salt)
что эквивалентно
md5( 0xC4CA4238A0B923820DCC509A6F75849B || "1" || `null` )
что эквивалентно
md5( 0xC4CA4238A0B923820DCC509A6F75849B31 )
(обратите внимание, что ASCII "1" становится конкатенированным 0x31 в конце значения D_1
)
который оказывается:
0x7976c7161415c830816dd4068a1d9a52
это то, что эта справочная страница называет D_2.
Ключу нужно всего на 8 байтов больше, чем доказано D_1
, поэтому он берет первые 8 байтов D_2 и становится:
Key: C4CA4238A0B923820DCC509A6F75849B7976c7161415c830
IV требуется всего 8 байтов, и, поскольку в D_2 есть 8 неиспользуемых байтов, они становятся IV:
IV: 816dd4068a1d9a52
Вот командная строка для генерации D_1, первых 16 байтов ключа (учитывая ваш пример пароля "1" и --nosalt
):
echo -n "1" | openssl md5
Вот командная строка для генерации D_2, оставшиеся 8 байтов ключа плюс все 8 байтов IV (опять же, учитывая ваши входные данные примера):
echo -n "$(echo -n "1" | openssl md5 -binary)1" | md5
Это работает, принимая вывод D_1 (следя за тем, чтобы сохранить его в двоичном формате, а не переводя его в шестнадцатеричные цифры в кодировке ASCII), добавляя к нему "1" (0x31) и получая md5
этого.