PHP 7.2中mcrypt_encrypt的精确替代

use*_*906 5 php encryption phpseclib

由于PHP 7.2中不再支持mcrypt_encrypt,因此我正在尝试完全替换此函数.

在阅读了许多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);
    }
Run Code Online (Sandbox Code Playgroud)

我的钥匙和IV是

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

  $iv = '741952hheeyy66#cs!9hjv887mxx7@8y';
Run Code Online (Sandbox Code Playgroud)

前42个字符是相同的,但其余的是不同的,你可以看到

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

mcrypt_encrypt输出:
3uw7mVZthiIPPNosvppZHd1jEau3Ul + 0BQ4AVS2t80skauq3Zv9z5uztvmiBpYqQcKGIDP5YHfdEBhPBfdVbxg ==

phpseclib输出:
3uw7mVZthiIPPNosvppZHd1jEau3Ul + 0BQ4AVS2t80tKnjjxVhuAwh3E1S5OnH1up5AujvQu1Grgyv16tNIEDw ==

我需要生成相同的加密文本,因为这个文本由另一个我无法更改的程序解密.

所以我的问题是,是否可以使用phpseclib或任何其他方式生成与mcrypt_encrypt相同的加密文本?

Tsc*_*cka 7

您可能需要“填充所有东西”

如果您在leaseweb 上阅读此条目,它会一遍又一遍地说明mcrypt 会自动将事物填充到它可以咀嚼的正确块大小。由于所有空字节,这当然会导致不同的输出。

因此,我建议您确保输入到 phpseclib 代码中的所有数据都填充了正确数量的空字节,以模拟输入 mcrypt 输入到密码中。

默认情况下,如果您查看PHPSECLIB代码,它会填充一个由要填充的字符数决定的字符。
mcrypt 但是用字符 0 填充。

所以,让我们解决这个问题。

您需要更改的代码是:

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

在 github 上使用了最新版本的PHPSECLIB 作为 avaialble,所以我的代码与您的示例代码不同。这是我机器上的完整工作示例。

<?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);
Run Code Online (Sandbox Code Playgroud)

显示输出

  • @user1918906 花了我 1.5 小时的实验时间,但它肯定对其他人更有用,所以值得 :-) (2认同)