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

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

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

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

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

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

для mcrypt

"Y + JgMBdfI7ZYY3M9lJXCtb5Vgu + rWvLBfjug2GLX7uo ="

for for openssl

"Y + JgMBdfI7ZYY3M9lJXCtb5Vgu + rWvLBvte4swdttHY ="

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

Не используется OPENSSL_ZERO_PADDING или OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING работает … 🙁

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

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

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 

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

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