Заменить Mcrypt на OpenSSL

В настоящее время мы используем mcrypt для наших систем для склеивания некоторых разумных данных в нашем приложении PHP. Теперь у нас есть новое требование, чтобы мы изменили модуль склепа на openssl. Еще одна важная вещь заключается в том, что мы используем шифр blowfish и режим ecb. Поэтому я начал проверять, что такое различия, и как я могу расшифровать зашифрованные строки с помощью sscript с помощью openssl.

Я использовал стандартную функцию PHP:

  • mcrypt_encrypt vs. openssl_encrypt
  • mcrypt_decrypt vs. openssl_decrypt

Оба метода предоставляют разные результаты. Во-вторых, в данном шифре (blowfish) и режиме (ecb) в обоих типах требуются разные IV долготы (openssl = 0 и mcrypt = 56).

Кто-нибудь знает, как я могу легко изменять модули без больших усилий по переносу?

Спасибо заранее!

UPDATE:

Вот код, который я тестировал:

<?php 

function say($message){
    if(!is_string($message)){
        if(!isset($_SERVER["HTTP_USER_AGENT"])) echo "<pre>";
        echo var_export($message, true) . ((!isset($_SERVER["HTTP_USER_AGENT"]) ? "\n" : "<br />"));
        if(!isset($_SERVER["HTTP_USER_AGENT"])) echo "</pre>";
    }else{
        echo $message . ((!isset($_SERVER["HTTP_USER_AGENT"]) ? "\n" : "<br />"));
    }
}

say("= Begin raw encryption");
$key    = "anotherpass";
$str    = "does it work";

say("  Params:");
say("  - String to encrypt '".$str."'");
say("  - Key: ".$key);
say("");


$params = array(
    "openssl"  => array(
        "cipher"    => "BF",
        "mode"      => "ECB",
    ),
    "mcrypt" => array(
        "cipher"    => "blowfish", 
        "mode"      => "ecb",
    ),
);

say("= Mcrypt");
$handler = mcrypt_module_open($params['mcrypt']['cipher'], '', $params['mcrypt']['mode'], '');
$iv      = mcrypt_create_iv (mcrypt_enc_get_iv_size($handler), MCRYPT_RAND);
$keysize = mcrypt_enc_get_key_size($handler);
mcrypt_generic_init($handler,$key,"\0\0\0\0\0\0\0\0");
say("  Params:");
say("  - InitVector   ".bin2hex($iv)." (bin2hex)");
say("  - Max keysize  ".$keysize);
say("  - Cipher       ".$params['mcrypt']['cipher']);
say("  - Mode         ".$params['mcrypt']['mode']);
say("");
say("  Encryption:");
$m_encrypted = mcrypt_generic($handler, $str);
$m_decrypted = mdecrypt_generic($handler, $m_encrypted);
say("  - Encrypted   ".bin2hex($m_encrypted)." (bin2hex)");
say("  - Descrypted  ".$m_decrypted);
say("");


say("= Openssl");
say("  Params:");
say("  - InitVector   not needed");
say("  - Max keysize  ".openssl_cipher_iv_length($params['openssl']['cipher']."-".$params['openssl']['mode']));
say("  - Cipher       ".$params['openssl']['cipher']);
say("  - Mode         ".$params['openssl']['mode']);
say("");
say("  Encryption:");
$o_encrypted = openssl_encrypt($str,$params['openssl']['cipher']."-".$params['openssl']['mode'],$key,true);
$o_decrypted = openssl_decrypt($o_encrypted,$params['openssl']['cipher']."-".$params['openssl']['mode'],$key,true);
say("  - Encrypted   ".bin2hex($o_encrypted)." (bin2hex)");
say("  - Descrypted  ".$o_decrypted);

И это мой результат:

= Begin raw encryption
  Params:
  - String to encrypt 'does it work'
  - Key: anotherpass

= Mcrypt
  Params:
  - InitVector   06a184909d7bf863 (bin2hex)
  - Max keysize  56
  - Cipher       blowfish
  - Mode         ecb

  Encryption:
  - Encrypted   0e93dce9a6a88e343fe5f90d1307684c (bin2hex)
  - Descrypted  does it work

= Openssl
  Params:
  - InitVector   not needed
  - Max keysize  0
  - Cipher       BF
  - Mode         ECB

  Encryption:
  - Encrypted   213460aade8f9c14d8d51947b8231439 (bin2hex)
  - Descrypted  does it work

Возможно, теперь какие-нибудь идеи?

Спасибо!

Ответ 1

Blowfish - это блок-шифр. Для шифрования данных требуется, чтобы данные были дополнены. OpenSSL использует PKCS # 7, а mcrypt использует PKCS # 5. Различные атрибуты заполнения для данных. Минимальная длина заполнения PKCS # 5 равна 0, для PKCS # 7 это 1 (wikipedia). Взгляните на этот пример (у меня вручную введенные входные данные для mcrypt_encrypt() в стиле PKCS # 7):

<?php 

$key = "anotherpassword1";
$str = "does it work 12";

$enc = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $str."\1", MCRYPT_MODE_ECB);
$dec = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $enc, MCRYPT_MODE_ECB);
echo(bin2hex($enc).PHP_EOL);
var_dump($dec);

$enc = openssl_encrypt($str, 'bf-ecb', $key, true);
$dec = openssl_decrypt($enc, 'bf-ecb', $key, true);
echo(bin2hex($enc).PHP_EOL);
var_dump($dec);

?>

Невозможно открыть данные openssl_decrypt(), зашифрованные с помощью mcrypt_encrypt(), если не было сделано ручное заполнение данных с помощью PKCS # 7 до mcrypt_encrypt().

В вашем случае есть только один способ - перекодировать данные.

PS: В вашем источнике есть ошибка - режим ECB вообще не использует IV (wikipedia)