通过mcrypt加密,并通过opensl以CBC模式和密码BLOWFISH解密

Man*_*han 5 php encryption openssl mcrypt

我们已经使用mcrypt密码对一些数据进行了加密,BLOWFISH并且模式为CBC String加密,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;
Run Code Online (Sandbox Code Playgroud)

上面的代码没有解密字符串。请建议我任何解密字符串的方法

Rei*_*eek 2

您错过了一个选项opensslOPENSSL_DONT_ZERO_PAD_KEY

如果给定的密钥长度openssl_decrypt()短于密码的默认密钥长度(在本例中为 Blowfish),PHPopenssl粘合代码会通过添加额外的零来将密钥扩展到该长度。你可以在这里看到它发生的情况。该mcrypt实现不会进行按键填充。Blowfish 的默认密钥长度openssl为 16 字节,因此如果您的密钥短于 16 字节,则 和 的密钥mcryptopenssl有所不同 - 除非您使用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;
Run Code Online (Sandbox Code Playgroud)

$ php bf.php
Lorem ipsum
Run Code Online (Sandbox Code Playgroud)

tmadam 的评论也很相关,涉及末尾的零。扩展该建议:

var_dump($decrypted);
var_dump(rtrim($decrypted));
Run Code Online (Sandbox Code Playgroud)

给出

string(16) "Lorem ipsum"
string(11) "Lorem ipsum"
Run Code Online (Sandbox Code Playgroud)

当然,您不能rtrim对二进制数据执行此操作,在这种情况下,您将必须记住或存储原始明文的大小,或者根据一些有用的填充模式(而不是零填充)手动填充数据。mcrypt_encrypt()似乎没有能力做到这一点。