通过 mcrypt 加密并通过 openssl 使用模式 CBC 和密码 BLOWFISH 解密
Encrypt by mcrypt and decrypt by openssl with mode CBC and cipher BLOWFISH
我们已经用 mcrypt 密码 BLOWFISH
加密了一些数据,模式是 CBC
字符串在 php5.5
中加密,需要在 php7.1
中解密(php 版本升级)
以下是我们尝试使用 openssl
解密 mcrypt 字符串的代码
$data = "Lorem ipsum";
$key = "12345678";
$iv = "12345678";
$encrypted = mcrypt_encrypt(
MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC, $iv);
echo $encrypted . PHP_EOL;
$decrypted = openssl_decrypt(
$encrypted, "BF-CBC", $key,
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
echo $decrypted;
以上代码不是解密字符串。
请建议我任何解密字符串的方法
您在 openssl
一侧遗漏了一个选项:OPENSSL_DONT_ZERO_PAD_KEY
。
如果给 openssl_decrypt()
的密钥长度短于密码的默认密钥长度(在本例中为 Blowfish),PHP openssl
胶水代码会扩展密钥通过添加额外的零来达到该长度。你可以看到它发生 here。 mcrypt
实现不执行该键填充。 Blowfish 的 openssl
默认密钥长度为 16 字节,因此如果您的密钥短于 16 字节,则 mcrypt
和 openssl
的密钥将不同——除非您使用 openssl
不对键进行填充的选项。
验证确实如此:
# bf.php
$data = "Lorem ipsum";
$key = "12345678";
$iv = "12345678";
$encrypted = mcrypt_encrypt(
MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC, $iv);
#echo $encrypted . PHP_EOL;
$decrypted = openssl_decrypt(
$encrypted, "BF-CBC", $key,
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING | OPENSSL_DONT_ZERO_PAD_KEY, $iv);
echo $decrypted . PHP_EOL;
和
$ php bf.php
Lorem ipsum
也与末尾的零有关。扩展该建议:
var_dump($decrypted);
var_dump(rtrim($decrypted));
给予
string(16) "Lorem ipsum"
string(11) "Lorem ipsum"
你当然不能对二进制数据做rtrim
,在那种情况下你必须记住或存储原始明文的大小,或者根据一些有用的填充模式手动填充数据与零填充相反。 mcrypt_encrypt()
似乎做不到。
我们已经用 mcrypt 密码 BLOWFISH
加密了一些数据,模式是 CBC
字符串在 php5.5
中加密,需要在 php7.1
中解密(php 版本升级)
以下是我们尝试使用 openssl
解密 mcrypt 字符串的代码$data = "Lorem ipsum";
$key = "12345678";
$iv = "12345678";
$encrypted = mcrypt_encrypt(
MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC, $iv);
echo $encrypted . PHP_EOL;
$decrypted = openssl_decrypt(
$encrypted, "BF-CBC", $key,
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
echo $decrypted;
以上代码不是解密字符串。 请建议我任何解密字符串的方法
您在 openssl
一侧遗漏了一个选项:OPENSSL_DONT_ZERO_PAD_KEY
。
如果给 openssl_decrypt()
的密钥长度短于密码的默认密钥长度(在本例中为 Blowfish),PHP openssl
胶水代码会扩展密钥通过添加额外的零来达到该长度。你可以看到它发生 here。 mcrypt
实现不执行该键填充。 Blowfish 的 openssl
默认密钥长度为 16 字节,因此如果您的密钥短于 16 字节,则 mcrypt
和 openssl
的密钥将不同——除非您使用 openssl
不对键进行填充的选项。
验证确实如此:
# bf.php
$data = "Lorem ipsum";
$key = "12345678";
$iv = "12345678";
$encrypted = mcrypt_encrypt(
MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC, $iv);
#echo $encrypted . PHP_EOL;
$decrypted = openssl_decrypt(
$encrypted, "BF-CBC", $key,
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING | OPENSSL_DONT_ZERO_PAD_KEY, $iv);
echo $decrypted . PHP_EOL;
和
$ php bf.php
Lorem ipsum
var_dump($decrypted);
var_dump(rtrim($decrypted));
给予
string(16) "Lorem ipsum"
string(11) "Lorem ipsum"
你当然不能对二进制数据做rtrim
,在那种情况下你必须记住或存储原始明文的大小,或者根据一些有用的填充模式手动填充数据与零填充相反。 mcrypt_encrypt()
似乎做不到。