PHP 7.2中mcrypt_encrypt的精确替代
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP 7.2中mcrypt_encrypt的精确替代相关的知识,希望对你有一定的参考价值。
由于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);
}
我的钥匙和IV是
$ky = 'lkirwf897+22#bbtrm8814z5qq=498j5';
$iv = '741952hheeyy66#cs!9hjv887mxx7@8y';
前42个字符是相同的,但其余的是不同的,你可以看到
要加密的文本:57F0-ECD3-1A3B-341E-BA39-F81B-F020-0DE0
mcrypt_encrypt输出: 3uw7mVZthiIPPNosvppZHd1jEau3Ul + 0BQ4AVS2t80skauq3Zv9z5uztvmiBpYqQcKGIDP5YHfdEBhPBfdVbxg ==
phpseclib输出: 3uw7mVZthiIPPNosvppZHd1jEau3Ul + 0BQ4AVS2t80tKnjjxVhuAwh3E1S5OnH1up5AujvQu1Grgyv16tNIEDw ==
我需要生成相同的加密文本,因为这个文本由另一个我无法更改的程序解密。
所以我的问题是,是否可以使用phpseclib或任何其他方式生成与mcrypt_encrypt相同的加密文本?
你可能需要“填补所有东西”
如果你读过这个entry on leaseweb,它就会一遍又一遍地说明mcrypt会自动填充到可以咀嚼的正确块大小。由于所有空字节,这当然导致不同的输出。
所以我建议你确保你输入到phpseclib代码中的所有数据都填充了正确的空字节数,以模拟输入密码输入到密码中。
默认情况下,如果您查看code of PHPSECLIB,它会填充由填充字符数决定的字符。 然而mcrypt填充字符0。
所以,让我们解决这个问题。
您需要更改的代码是:
$cipher->disablePadding();
$length = strlen($text);
$pad = 32 - ($length % 32);
$text = str_pad($text, $length + $pad, chr(0));
我使用了最新版本的PHPSECLIB as avaialble on github,因此我的代码与您的示例代码不同。这是我机器上的完整工作示例。
<?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 phpseclibCryptRijndael 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 "
";
$text = encryptRJ256($secret, $iv, $text);
echo $text;
echo "
";
echo decryptRJ256($secret, $iv, $text);
以上是关于PHP 7.2中mcrypt_encrypt的精确替代的主要内容,如果未能解决你的问题,请参考以下文章
mcrypt_encrypt 不同的结果在 php 和 ios
在 PHP 中将 mcrypt_encrypt 转换为 openssl_encrypt
CryptoJS 中 CFB 模式中的 mcrypt_encrypt 函数
.NET WebService 加密 -> PHP 解密错误:mcrypt_encrypt(): IV 参数必须与块大小一样长