php: шифрование mcrypt для шифрования openssl и проблемы с заполнением OpenSSL

у меня есть этот вызов mcrypt_encrypt, для данного $ key, $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.2 g 1 Mar 2016".

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

2 ответов


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, "");
}
$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

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

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