从mcrypt_encrypt()迁移到openssl_encrypt()

时间:2018-12-10 06:32:03

标签: php openssl

我被迫从PHP 5.6迁移到7.0+,一切正常,除了mcrypt_encrypt(),它已经被弃用,如php.net中所述。

这是我的代码

$json = array(
    'Amount' => $amount
);

$data = json_encode($json);

function encrypt($data, $secret) 
{ 
    //Generate a key from a hash 
    $key    = md5(utf8_encode($secret), true); 
    $data2  = utf8_encode($data); 
    $iv     = utf8_encode("jvz8bUAx"); 

    //Take first 8 bytes of $key and append them to the end of $key. 
    $key .= substr($key, 0, 8); 

    //Pad for PKCS7 
    $blockSize = mcrypt_get_block_size('tripledes', 'cbc'); 

    //Encrypt data 
    $encData = mcrypt_encrypt('tripledes', $key, $data2, MCRYPT_MODE_CBC, $iv); 

    return urlencode(base64_encode($encData)); 
} 

我想用openssl_encrypt替换不赞成使用的行。

function encrypt($data, $secret) 
{ 
    //Generate a key from a hash 
    $key    = md5(utf8_encode($secret), true); 
    $data   = utf8_encode($data); 
    $iv     = utf8_encode("jvz8bUAx"); 

    $method = 'AES-256-CBC';

    $encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA, $iv);

    $encrypted = base64_encode($iv . $encrypted);

    return $encrypted;
} 

错误:

  

传递的IV仅8个字节长,密码期望IV恰好为16   字节,以\ 0

填充

我缺少什么?

更新:添加解密部分

 function decrypt($data, $secret) 
    { 
    //Generate a key from a hash 
    $data = urldecode($data); 
    $iv    = utf8_encode("jvz8bUAx"); 
    $key   = md5(utf8_encode($secret), true); 

    // Take first 8 bytes of $key and append them to the end of $key. 
    $key .= substr($key, 0, 8); 

    $data3 = base64_decode($data); 

    return $data4 = mcrypt_decrypt('tripledes', $key, $data3, MCRYPT_MODE_CBC, $iv); 

} 

1 个答案:

答案 0 :(得分:0)

已更新

因此,您正在寻找des-ede3-cbc Openssl算法。

一种获取服务器上所有openssl算法列表的便捷方法是运行:

 print_r(openssl_get_cipher_methods(TRUE));

这将生成一个列表,以供参考。

似乎也存在填充问题。 Mcrypt在加密例程期间添加了填充,而Openssl没有。因此,您必须在Openssl的加密方面添加填充。我们还需要在openssl函数中强制使用no_padding。

这些功能现在应该对您有用。

function encryptNew($data, $secret){

  //Generate a key from a hash
  $key    = md5(utf8_encode($secret), true);
  $data   = utf8_encode($data);
  $iv     = utf8_encode("jvz8bUAx");

  //Take first 8 bytes of $key and append them to the end of $key.
  $key .= substr($key, 0, 8); //You key size has to be 192 bit for 3DES.

  $method = 'des-ede3-cbc'; //<----Change you method to this...

  //Mcrypt adds padding inside the function.  Openssl does not. So we have to pad the data.
  if (strlen($data) % 8) {

    $data = str_pad($data, strlen($data) + 8 - strlen($data) % 8, "\0");

  }

  $encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); //Force zero padding.

  $encrypted = urlencode(base64_encode($encrypted)); //Added the urlencode.....

  return $encrypted;

}


function decryptNew($data, $secret){

  //$data = base64_decode(urldecode($data));//<--If you have raw data coming in this needs to be commented out. 
  $iv    = utf8_encode("jvz8bUAx");
  $key   = md5(utf8_encode($secret), true);

  // Take first 8 bytes of $key and append them to the end of $key.
  $key .= substr($key, 0, 8);

  $method = 'des-ede3-cbc';

  return openssl_decrypt($data, $method, $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv); //Force zero padding.

}

希望这会有所帮助。