Шифрование / дешифрование openSSL между ПК с Windows и PHP, работающим на веб-сервере Linux

Я пытаюсь научиться выполнять простое шифрование/дешифрование между компьютером с Windows 64 (мой компьютер) и PHP, работающим на веб-сервере Linux с использованием openSSL.

На моем компьютере с Windows я установил OpenSSL v1.0.2k для Win64 и использую следующую команду для создания зашифрованной строки с использованием простого пароля и простого ключа, расположенного в файле secretkey.txt.

enc -aes-256-cbc -A -base64 -nopad -nosalt -pass pass:hello -in secretkey.txt

Когда я запускаю команду выше, я получаю следующую строку:

3WE7cuBFhuLCn3/ZBnUrBn68nn3tVn0NKKz63B3uvoc=

Используя приведенную выше строку, я ожидаю, что PHP на моем веб-сервере Linux сможет расшифровать ее следующим образом:

 $encrypted = '3WE7cuBFhuLCn3/ZBnUrBn68nn3tVn0NKKz63B3uvoc=';
 $enc = 'aes-256-cbc';
 $password = 'hello';
 $key = openssl_decrypt($encrypted, $enc, $password, OPENSSL_ZERO_PADDING);
 echo $key .' should equal this-1234-is-4567-my-8910-secret';

Но вместо этого я получаю это:

9(j����T]��$�W�Ma��S�è��zz�>.( должно быть равно this-1234-is-4567-my-8910-secret

Я просмотрел следующие сайты и попробовал несколько версий, но не могу правильно расшифровать:

Открыть SSL Enc
Открыть командную строку SSL
Расшифровка PHP


person Marc    schedule 16.02.2017    source источник
comment
не дубликат. вопрос о попытке зашифровать из командной строки (windows) и расшифровать с помощью php. рекомендуемое решение связано с шифрованием и дешифрованием всего в PHP.   -  person Marc    schedule 16.02.2017
comment
Вы base64 декодируете вывод openssl в своем PHP-коде?   -  person President James K. Polk    schedule 17.02.2017
comment
Заполнение нулями — плохая идея, обычно используется заполнение PKCS#7 (урожденное PKCS#5). Нулевое заполнение не позволит зашифровать двоичные данные, которые заканчиваются нулевым (0x00) байтом.   -  person zaph    schedule 17.02.2017


Ответы (1)


Для работы AES требуется ключ. Это последовательность байтов точно такой же длины (32 в случае AES-256). Вы не можете напрямую использовать пароль (если только байты, из которых состоит пароль, не имеют нужной длины).

Кроме того, режим CBC требует вектора инициализации (IV) 16 байт.

Команда OpenSSL enc получает ключ и IV для использования из пароля, предоставленного с помощью внутренней функции EVP_BytesToKey. Чтобы расшифровать файл, зашифрованный с помощью enc, вам необходимо воспроизвести эту функцию. Подробности алгоритма в документации. В PHP это может выглядеть так:

$password = 'hello';

$bytes = "";
$last = "";

// 32 bytes key + 16 bytes IV = 48 bytes.
while(strlen($bytes) < 48) {
    $last = md5($last . $password, true);
    $bytes.= $last;
}

// First 32 bytes are the key, next 16 are the IV.
$key = substr($bytes, 0, 32);
$iv = substr($bytes, 32, 16);

Затем вы можете использовать эти значения в команде openssl_decrypt:

$enc = 'aes-256-cbc';
$result = openssl_decrypt($encrypted, $enc, $key, OPENSSL_ZERO_PADDING, $iv);
person matt    schedule 17.02.2017