简体   繁体   English

PHP 7.2中mcrypt_encrypt的精确替代

[英]Exact alternate to mcrypt_encrypt in PHP 7.2

Since mcrypt_encrypt is no longer supported in PHP 7.2, I am trying for exact alternate to this function. 由于PHP 7.2中不再支持mcrypt_encrypt,因此我正在尝试完全替换此函数。

After reading many SO answers I have found the following code which uses PHPSECLIB, but it's not producing the exact encrypted text as mcrypt. 在阅读了许多SO答案后,我发现以下代码使用了PHPSECLIB,但它并没有像mcrypt那样生成确切的加密文本。

function encryptRJ256($key,$iv,$string_to_encrypt)
    {

       // $rtn = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $string_to_encrypt, MCRYPT_MODE_CBC, $iv);

      $rijndael = new Crypt_Rijndael(CRYPT_RIJNDAEL_MODE_CBC);  
      $rijndael->setKey($key);
      $rijndael->setIV($iv);
      $rijndael->setKeyLength(256);
      $rijndael->disablePadding();
      $rijndael->setBlockLength(256);
      $rtn = $rijndael->encrypt($string_to_encrypt);    
      $rtn = base64_encode($rtn);
      return($rtn);
    }

My Key and IV is 我的钥匙和IV是

  $ky = 'lkirwf897+22#bbtrm8814z5qq=498j5'; 

  $iv = '741952hheeyy66#cs!9hjv887mxx7@8y';

The first 42 chars are equal but the rest is different as you can see 前42个字符是相同的,但其余的是不同的,你可以看到

Text to encrypt: 57F0-ECD3-1A3B-341E-BA39-F81B-F020-0DE0 要加密的文本:57F0-ECD3-1A3B-341E-BA39-F81B-F020-0DE0

mcrypt_encrypt output: mcrypt_encrypt输出:
3uw7mVZthiIPPNosvppZHd1jEau3Ul+0BQ4AVS2t80skauq3Zv9z5uztvmiBpYqQcKGIDP5YHfdEBhPBfdVbxg== 3uw7mVZthiIPPNosvppZHd1jEau3Ul + 0BQ4AVS2t80skauq3Zv9z5uztvmiBpYqQcKGIDP5YHfdEBhPBfdVbxg ==

phpseclib output: phpseclib输出:
3uw7mVZthiIPPNosvppZHd1jEau3Ul+0BQ4AVS2t80tKnjjxVhuAwh3E1S5OnH1up5AujvQu1Grgyv16tNIEDw== 3uw7mVZthiIPPNosvppZHd1jEau3Ul + 0BQ4AVS2t80tKnjjxVhuAwh3E1S5OnH1up5AujvQu1Grgyv16tNIEDw ==

I need to produce the same encrypted text because this text is decrypted by another program which I can't change. 我需要生成相同的加密文本,因为这个文本由另一个我无法更改的程序解密。

So my question is, is it possible to produce the same encrypted text as mcrypt_encrypt using phpseclib or any other way? 所以我的问题是,是否可以使用phpseclib或任何其他方式生成与mcrypt_encrypt相同的加密文本?

You might need to "pad all the things" 你可能需要“填补所有东西”

If you read this entry on leaseweb it states over and over that mcrypt pads thing automatically to the correct block sizes that it can chew. 如果您在leaseweb上阅读此条目,它会反复声明该mcrypt会自动填充到可以咀嚼的正确块大小。 That leads of course to different outputs because of all the null bytes. 由于所有空字节,这当然导致不同的输出。

So I'd suggest you make sure all your data you feed into your phpseclib code are padded with the correct amount of null bytes to simulate the input mcrypt feeds into the cipher. 所以我建议你确保你输入到phpseclib代码中的所有数据都填充了正确的空字节数,以模拟输入密码输入到密码中。

Default if you look at the code of PHPSECLIB it pads by a character decided by the number of characters to pad. 默认情况下,如果您查看PHPSECLIB代码,它将填充填充字符数决定的字符。
mcrypt however pads with character 0. 然而mcrypt填充字符0。

So, let's fix this. 所以,让我们解决这个问题。

The changed code you need is: 您需要更改的代码是:

    $cipher->disablePadding();
    $length = strlen($text);
    $pad = 32 - ($length % 32);
    $text = str_pad($text, $length + $pad, chr(0));

I used the latest version of PHPSECLIB as avaialble on github , so my code differs from your example code. 在github上使用了最新版本的PHPSECLIB作为avaialble ,因此我的代码与您的示例代码不同。 This is the full working example on my machine. 这是我机器上的完整工作示例。

<?php 
include "vendor/autoload.php";
include "phpseclib/bootstrap.php";
set_include_path(get_include_path() . PATH_SEPARATOR . 'phpseclib');
include('Crypt/Rijndael.php');
include('Crypt/Random.php');
use phpseclib\Crypt\Rijndael as Crypt_Rijndael;

$text = '57F0-ECD3-1A3B-341E-BA39-F81B-F020-0DE0';

$secret = 'lkirwf897+22#bbtrm8814z5qq=498j5';

$iv = '741952hheeyy66#cs!9hjv887mxx7@8y';

function encrypt128($secret, $iv, $str)
{ 

    return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $secret, $str, MCRYPT_MODE_CBC, $iv));
}

function encryptRJ256($key,$iv,$text)
{
    $cipher = new Crypt_Rijndael('cbc'); 
    $cipher->setBlockLength(256);
    // keys are null-padded to the closest valid size
    // longer than the longest key and it's truncated
    $cipher->setKeyLength(256);
    $cipher->setKey($key);
    // the IV defaults to all-NULLs if not explicitly defined
    $cipher->setIV($iv);
    $cipher->disablePadding();
    $length = strlen($text);
    $pad = 32 - ($length % 32);
    $text = str_pad($text, $length + $pad, chr(0));
    return base64_encode($cipher->encrypt($text));
}
function decryptRJ256($key,$iv,$text)
{
    $cipher = new Crypt_Rijndael('cbc'); // could use CRYPT_RIJNDAEL_MODE_CBC
    $cipher->setBlockLength(256);
    // keys are null-padded to the closest valid size
    // longer than the longest key and it's truncated
    $cipher->setKeyLength(256);
    $cipher->setKey($key);
    // the IV defaults to all-NULLs if not explicitly defined
    $cipher->setIV($iv);
    $cipher->disablePadding();
    return $cipher->decrypt(base64_decode($text)); 
}   

echo $text;
echo encrypt128($secret, $iv, $text);
echo "\n";
$text = encryptRJ256($secret, $iv, $text);
echo $text;
echo "\n";
echo decryptRJ256($secret, $iv, $text);

显示输出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM