openssl — php: mcrypt_encrypt to openssl_encrypt и проблемы OPENSSL_ZERO_PADDING

У меня есть вызов mcrypt_encrypt для данного ключа $, $ message и $ iv:

$string = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv);

Я хотел бы изменить mcrypt_encrypt позвонить openssl_encrypt Во-первых, чтобы защитить это на будущее.

Имея $mode = 'des-ede3-cbc' или же $mode = '3DES'; а также $options = true Я получаю более похожий ответ, но не идентичный. Есть ли другой способ назвать это, чтобы получить идеальное совпадение?

Я получаю это (base64_encoded) для Lorem-Ipsum $message+$key комбинации, так что я начинаю верить, что одна или другая функция несколько расширяют сообщение перед шифрованием …

для Mcrypt

«Y + JgMBdfI7ZYY3M9lJXCtb5Vgu + rWvLBfjug2GLX7uo =»

для для OpenSSL

«Y + JgMBdfI7ZYY3M9lJXCtb5Vgu + rWvLBvte4swdttHY =»

Пробовал использовать $ options для передачи OPENSSL_ZERO_PADDING, но передавая все, кроме 1 (OPENSSL_RAW_DATA, или же правда) приводит к пустой строке …

Ни с помощью OPENSSL_ZERO_PADDING ни OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING Работа… 🙁

Любые другие подсказки? Я использую «OpenSSL 1.0.2g 1 марта 2016».

Уже прочитал этот Q&а, но это не помогает мне Не только один с проблемами прокладки, но пока не видно решения. (Второй ответ говорит о добавление заполнение до вызова mcrypt, я бы очень хотел Удалить дополнение от вызова шифрования openssl …

12

Решение

mcrypt_encrypt входные данные с нуля, если они не кратны размеру блока. Это приводит к неоднозначным результатам, если сами данные имеют конечные нули. Очевидно, OpenSSL не позволяет вам использовать заполнение нулями в этом случае, что объясняет ложное возвращаемое значение.

Вы можете обойти это, добавив отступ вручную.

$message = "Lorem ipsum";
$key = "123456789012345678901234";
$iv = "12345678";

$message_padded = $message;
if (strlen($message_padded) % 8) {
$message_padded = str_pad($message_padded,
strlen($message_padded) + 8 - strlen($message_padded) % 8, "\0");
}
$encrypted_mcrypt = mcrypt_encrypt(MCRYPT_3DES, $key,
$message, MCRYPT_MODE_CBC, $iv);
$encrypted_openssl = openssl_encrypt($message_padded, "DES-EDE3-CBC",
$key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);

printf("%s => %s\n", bin2hex($message), bin2hex($encrypted_mcrypt));
printf("%s => %s\n", bin2hex($message_padded), bin2hex($encrypted_openssl));

Это печатает как равные.

4c6f72656d20697073756d => c6fed0af15d494e485af3597ad628cec
4c6f72656d20697073756d0000000000 => c6fed0af15d494e485af3597ad628cec
19

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

mcrypt_encrypt использует нули для заполнения сообщения до размера блока. Таким образом, вы можете добавить нули в конец ваших необработанных данных, а затем зашифровать блок.

С помощью OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING должно сработать. Если этого не произойдет, вы можете удалить отступы из расшифрованных данных самостоятельно.

-3