Совместимость шифрования между TCL и openssl

439
Aditya Mayank Shankar

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

например, выходной шифр сценария tcl и сценария оболочки должен быть одинаковым. Механизм шифрования, который я хочу использовать, - это AES или DES. (и я открыт для использования любого механизма шифрования на самом деле)

Проблема в том, что оба скрипта создают разные зашифрованные тексты.

В tcl я использую следующую команду:

[aes::aes -mode cbc -dir encrypt -key 1234567891012345 hi] 

и в сценарии оболочки:

echo -n "hi" | openssl enc -aes-128-cbc -nosalt -pass pass:1234567891012345 

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

Есть ли способ сделать один и тот же зашифрованный текст, используя разные сценарии?

1

1 ответ на вопрос

2
grawity

Если вы скажете openssl encиспользовать фразу-пароль, она всегда передается через KDF, никогда не используется непосредственно в качестве ключа; использование -nosaltне отключает это. (Вы можете использовать openssl enc -pопцию, чтобы увидеть, какой ключ и IV фактически используются.) Чтобы указать необработанный ключ, вам нужна -Kопция.

(Обратите внимание, что openssl enc -Kзначение, как ожидается, будет в шестнадцатеричном, в то же время aes::aes -keyинтерпретируется как необработанные двоичные данные.)

Другая проблема - отступы. Поскольку AES является блочным шифром, все входные данные должны быть дополнены до 16 байтов (размер блока AES), и существует несколько методов заполнения с различными свойствами безопасности. Модуль Tcl aesиспользует простое заполнение нулями, расширяя данные на 0x00 байт.

Между тем OpenSSL использует заполнение PKCS # 7 и заполняет блок значением, соответствующим размеру пэда. Например, если ваш ввод составляет всего 2 байта, ему нужно заполнить 14 байтов, поэтому в соответствии с PKCS # 7 каждый байт пэда также будет иметь значение 14 (0x0E).

( man encговорит о PKCS # 5, который является более старым документом, определяющим схему заполнения только для 8-байтовых блоков. PKCS # 7 позже определил точно такую ​​же схему для любого размера блока .)

Для режима CBC вам также необходимо указать IV (16 байтов, равный размеру блока AES). Модуль Tcl по умолчанию использует IV со всеми нулями. Хотя CBC использует IV только для 2-го и последующих блоков, это не влияет на вывод короткого текста.

Итак, в заключение, они дадут вам идентичные результаты (используя заполнение нулями):

aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex "hi"  printf 'hi\0\0\0\0\0\0\0\0\0\0\0\0\0\0' \ | openssl enc -aes-128-cbc -nopad \ -K 31323334353637383931303132333435 \ -iv 00000000000000000000000000000000 \ | hexdump -C 

Это также (используя заполнение PKCS # 7):

aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex \ "hi\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e"  printf 'hi' \ | openssl enc -aes-128-cbc \ -K 31323334353637383931303132333435 \ -iv 00000000000000000000000000000000 \ | hexdump -C 

Для реализации заполнения:

set data "hi" set pad [expr ] append data [string repeat [format %c $pad] $pad] aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex $data 
PKCS5 / 7 заполнение добавляется всегда, даже когда это полный блок (здесь 16). Кроме того, недокументированный забавный факт: «-iv 00» дополняется нулевыми байтами и легче вводится; то же самое для `-K`, если необходимо (не здесь). dave_thompson_085 6 лет назад 0
Спасибо за объяснение, и это избавило меня от многих сомнений. Я ценю вашу помощь @grawity У меня есть один вопрос. Как вы конвертируете ключ 1234567891012345 в 31323334353637383931303132333435? Aditya Mayank Shankar 6 лет назад 0
Нашел это! это шестнадцатеричное! Спасибо Aditya Mayank Shankar 6 лет назад 1

Похожие вопросы