首页 新闻 会员 周边 捐助

PHP7.4将mcrypt_encrypt升级为openssl_encrypt,加密结果不一致的问题?

0
悬赏园豆:100 [待解决问题]

PHP7.4将mcrypt_encrypt升级为openssl_encrypt,加密结果不一致的问题?

以下代码在PHP5.6环境下运行正常:

function priceEncode($enc_key, $price){
	$enc_key = base64_decode($enc_key);
	// PHP低版本使用,PHP7.1.0起废弃
	$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);

	$pad        = $size - (strlen($price) % $size);
	$price      = $price . str_repeat(chr($pad), $pad);

	$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
	$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
	mcrypt_generic_init($td, $enc_key, $iv);
	$data = mcrypt_generic($td, $price);
	mcrypt_generic_deinit($td);
	mcrypt_module_close($td);
	$data = base64_encode($data);

	return $data;
}

echo priceEncode('5AE8274196C85364D44938E47D80ACA6', 1222.01); // 得到cPnrXHxzWG6e0GyC7X/kpg==

在PHP7及以上版本,mcrypt扩展已被废弃,不再作为官方支持。上述示例如何在PHP7以上的版本实现呢?

echo base64_encode(openssl_encrypt($price, 'AES-128-ECB', $enc_key, OPENSSL_RAW_DATA));

使用openssl库,这样实现,输出的结果不一致是什么原因呢?

Sanplit的主页 Sanplit | 初学一级 | 园豆:104
提问于:2023-11-10 11:01
< >
分享
所有回答(2)
0

推荐使用openssl进行操作

function priceEncode($enc_key, $price){
    $enc_key = base64_decode($enc_key);
    $ivlen = openssl_cipher_iv_length($cipher="AES-128-ECB");
    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext_raw = openssl_encrypt($price, $cipher, $enc_key, $options=OPENSSL_RAW_DATA, $iv);
    $data = base64_encode($ciphertext_raw);
    return $data;
}
echo priceEncode('5AE8274196C85364D44938E47D80ACA6', 1222.01);
杨柳清风 | 园豆:204 (菜鸟二级) | 2023-11-10 13:04

目前是PHP7.4环境下,运行会报错Fatal error: Uncaught Error: Length must be greater than 0 in $iv 那行,AES-128-ECB模式下好像可以不用iv,这样返回的结果却是 jxGY821Kec6RKVxcjVIR1Q==

支持(0) 反对(0) Sanplit | 园豆:104 (初学一级) | 2023-11-10 13:14
0

问题可能出在两个加密函数的实现细节上。mcrypt_encrypt 和 openssl_encrypt 在一些参数和行为上可能有所不同,导致了不同的加密结果。

以下是您提供的 PHP5.6 版本代码的等效 PHP7.4 代码,使用 openssl_encrypt:

php

function priceEncode($enc_key, $price) {
$enc_key = base64_decode($enc_key);
$cipher = 'AES-128-ECB';

// PKCS7 padding
$pad = openssl_cipher_iv_length($cipher);
$price = openssl_encrypt($price, $cipher, $enc_key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
$price = $price . str_repeat(chr($pad - strlen($price) % $pad), $pad);

return base64_encode($price);

}

echo priceEncode('5AE8274196C85364D44938E47D80ACA6', 1222.01);
请注意以下几点:

使用 AES-128-ECB 作为加密算法。
使用 openssl_cipher_iv_length 来获取块大小。
使用 OPENSSL_RAW_DATA 和 OPENSSL_ZERO_PADDING 选项来进行加密和填充。
上述代码实现了在 PHP7.4 中使用 openssl_encrypt 替代 mcrypt_encrypt 的功能。然而,即便采用相同的加密算法和模式,不同的库和版本在具体实现上仍可能存在差异,因此结果可能会有轻微的不同。如果您确实需要与之前的加密结果完全相同,可能需要考虑其他一些因素,如补位方式等。

Technologyforgood | 园豆:7775 (大侠五级) | 2023-11-13 22:22

openssl_cipher_iv_length($cipher)有等于0的情况,作为除数会报错

支持(0) 反对(0) Sanplit | 园豆:104 (初学一级) | 2023-11-20 17:10
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册