PHP的mcrypt_encrypt和openssl(AES)输出是不同的

时间:2018-03-09 20:59:19

标签: php openssl mcrypt

我想从mcrypt_encrypt()转到openssl_encrypt()进行AES 256加密

但加密数据不同!

例如mcrypt_encrypt()输出:

Od2i8FHmWvMeXt+HwCy7k93koPVClK1erHsZwoB6sUE=

和openssl_encrypt()输出:

Od2i8FHmWvMeXt+HwCy7kyCt0nvHTaO4IdjdiF15LAc= 

我的代码:

<?php
$encryption_key = openssl_random_pseudo_bytes(32);
$iv = openssl_random_pseudo_bytes(16);
$data = "Here's some data to encrypt!";
$encrypted = openssl_encrypt($data, "aes-256-cbc", $encryption_key, 0, $iv);
echo "encrypted: $encrypted\n\n";
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $encryption_key, $data, MCRYPT_MODE_CBC, $iv));
echo "encrypted: $encrypted\n\n";
?>

有什么问题?谢谢

1 个答案:

答案 0 :(得分:1)

很可能是填充物。请注意,每个块的第一个块是相同的,最后一个块是不同的。

加密的文本是28个字节,因此最后一个块将有4个字节的填充:16-(28%16)= 4.

PHP mcrypt不支持标准的PKCS#7(néePKCS#5)填充,只支持非标准的空填充。

因此PHP mcrypt将指定4字节的0x00和openssl 4字节的0x04。请参阅PKCS#7 padding

因此,如果要使用openssl_encrypt创建相同的加密输出,则还需要指定零填充选项(OPENSSL_ZERO_PADDING自行添加空填充。注意:空填充不健壮,因为它无法正确处理所有二进制数据。

示例:openssl_encrypt($data, "aes-256-cbc", $encryption_key, OPENSSL_ZERO_PADDING, $iv);

mcrypt_encrypt():
Base64:Od2i8FHmWvMeXt+HwCy7k93koPVClK1erHsZwoB6sUE=
十六进制:39DDA2F051E65AF31E5EDF87C02CBB93 DDE4A0F54294AD5EAC7B19C2807AB141

openssl_encrypt:
Base64:Od2i8FHmWvMeXt+HwCy7kyCt0nvHTaO4IdjdiF15LAc=
十六进制:39DDA2F051E65AF31E5EDF87C02CBB93 20ADD27BC74DA3B821D8DD885D792C07