我目前正在用OpenSSL取代Mcrypt,因为Mcrypt将在PHP 7.1中被弃用。我需要的是一种获取每个算法的块大小的方法,如mcrypt_get_block_size()
。
我想知道是否有一个与mcrypt_get_block_size()
相同的功能,但它的记录非常糟糕似乎无法找到它。
答案 0 :(得分:1)
以下函数可用作PHP> = 5.4.0的替代。
它只是强制了openssl_encrypt()
之外的块长度。
if (!function_exists('openssl_cipher_block_length')) {
/**
* Returns the block length for a given cipher.
*
* @param string $cipher
* A cipher method (see openssl_get_cipher_methods()).
*
* @retval int
* The cipher's block length.
* Returns false if the actual length cannot be determined.
* Returns 0 for some cipher modes that do not use blocks
* to encrypt data.
*
* @note
* PHP >= 5.4.0 is required for this function to work.
*/
function openssl_cipher_block_length($cipher)
{
$ivSize = @openssl_cipher_iv_length($cipher);
// Invalid or unsupported cipher.
if (false === $ivSize) {
return false;
}
$iv = str_repeat("a", $ivSize);
// Loop over possible block sizes, from 1 upto 1024 bytes.
// The upper limit is arbitrary but high enough that is
// sufficient for any current & foreseeable cipher.
for ($size = 1; $size < 1024; $size++) {
$output = openssl_encrypt(
// Try varying the length of the raw data
str_repeat("a", $size),
// Cipher to use
$cipher,
// OpenSSL expands the key as necessary,
// so this value is actually not relevant.
"a",
// Disable data padding: php_openssl will return false
// if the input data's length is not a multiple
// of the block size.
//
// We also pass OPENSSL_RAW_DATA so that PHP does not
// base64-encode the data (since we just throw it away
// afterwards anyway)
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
// Feed it with an IV to avoid nasty warnings.
// The actual value is not relevant as long as
// it has the proper length.
$iv
);
if (false !== $output) {
return $size;
}
}
// Could not determine the cipher's block length.
return false;
}
}
答案 1 :(得分:1)
我认为你可以这样做:
$method = 'AES-256-CBC';
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($method));
$block_size = strlen(openssl_encrypt('', $method, '', OPENSSL_RAW_DATA, $iv));
它基本上加密了一个空字符串,并且,当数据填充到块大小时,检查结果长度。
我已经用一些不同的方法对它进行了测试,它似乎运行正常。
答案 2 :(得分:1)
更通用的方法可能会帮助您涉及使用此polyfill:mcrypt_compat。 polyfill是一个实现了尚不支持的功能的库。
步骤1 :使用Composer安装库
composer require phpseclib/mcrypt_compat
第2步:在使用mcrypt函数的PHP脚本顶部要求Composer的自动加载器(确保相对路径正确)
require_once('../vendor/autoload.php');
现在,您可以在此PHP脚本中使用mcrypt_get_block_size()
之类的功能
答案 3 :(得分:0)
php-openssl没有能够为您提供密码blockSize的API。如果确实需要它,则必须对blockSize进行硬编码(每种算法)。
但是,典型应用程序只需要支持单个加密算法,在这种情况下,您应该已经知道了大小写的大小。
此外,我mcrypt_get_block_size()
,mcrypt_enc_get_block_size()
的唯一用例是PKCS#7填充,OpenSSL 默认情况下已经使用进行分组密码算法。所以你可能根本就不需要这个。
答案 4 :(得分:0)
txigreman这个解决方案对我有用,我设法将MCRYPT代码更改为使用OPENSSL 这是我替换MCRYPT的加密功能,我混合了MCRYPT的一些代码和openssl的新代码,虽然解密不起作用,但是我可以打开提供商的付款页面并完成付款-这就是我需要的,之后将我重定向到成功页面,NeO.network.ae付款网关
public $method = 'aes-256-cbc';
$this->EncryptedString = $this->encryptData($this->beforeEncryptionString, $this->merchantKey, $this->method);
public function encryptData(string $data, string $key, string $method): string
{
$ivSize = openssl_cipher_iv_length($method);
$iv = 'YOUR_IV';
$size = strlen(openssl_encrypt('', $method, '', OPENSSL_RAW_DATA, $iv));
$pad = $size - ( strlen( $data ) % $size );
$padtext = $data . str_repeat( chr( $pad ), $pad );
$encrypted = openssl_encrypt($padtext, $method, base64_decode( $key ), OPENSSL_RAW_DATA, $iv);
$encrypted = base64_encode($encrypted);
return $encrypted;
}