用OpenSSLreplaceMcrypt

目前我们在我们的系统上实现了一个mcrypt实现,以在我们的PHP应用程序中隐藏一些合理的数据。 现在我们有一个新的要求,就是我们必须把crypt模块改成openssl。 另一件重要的事情就是我们正在使用密码河豚和模式ecb。 于是我开始testing什么是差异,以及如何使用openssl解密mcryptencryption的string。

我使用了标准的PHP函数:

  • mcrypt_encrypt与openssl_encrypt
  • mcrypt_decrypt与openssl_decrypt

两种方法都提供了不同的结果。 第二件事是在给定的密码(blowfish)和模式(ecb)中都需要不同的IV长度(openssl = 0和mcrypt = 56)。

有没有人知道我可以轻松地更改模块,而不需要大量的迁移工作?

提前致谢!

更新:

这是我testing的代码:

<?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 

也许现在有什么想法?

谢谢!

河豚是块密码。 它要求在encryption之前填充数据。 OpenSSL使用PKCS#7,而mcrypt使用PKCS#5。 不同的填充数据的algorythms。 最小PKCS#5填充长度为0,对于PKCS#7它是1( 维基百科 )。 看看这个例子(我已经手动填充了PKCS#7风格的mcrypt_encrypt()input数据):

 <?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); ?> 

除非在mcrypt_encrypt()之前使用PKCS#7手动填充数据,否则不可能使用mcrypt_encrypt()打开ssl_decrypt()数据。

你的情况只有一个办法 – 重新获得数据。

PS:在你的源代码中有错误 – ECB模式根本不使用IV( 维基百科 )