如何使用 OpenSSL 解密使用 ASCII 密钥的 Mcrypt 生成的值?
How to use OpenSSL to decrypt a value generated with Mcrypt that has used an ASCII key?
我需要能够使用 OpenSSL 解密在 PHP 下使用 Mcrypt 生成的值。
我有这个工作,除了用于加密它们的密钥是 ascii。
以下是我的代码,它演示了一个工作案例,当密钥是 MD5 时,OpenSSL 可以解密使用 Mcrypt 加密的值。
<?php
$message = 'test';
$key = md5('Quigibo');
$iv = openssl_random_pseudo_bytes(0);
$encrypted = mcrypt_encrypt(
MCRYPT_BLOWFISH,
$key,
$message,
MCRYPT_MODE_ECB,
$iv
);
$decrypted = openssl_decrypt(
$encrypted,
'bf-ecb',
$key,
OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,
$iv
);
$trimDecrypted = rtrim($decrypted);
var_export(
[
'Original message' => $message,
'Encrypted' => bin2hex($encrypted),
'Decrypted' => $decrypted,
'Trim decrypted' => $trimDecrypted,
'Message length' => mb_strlen($message, '8bit'),
'Decrypted length' => mb_strlen($decrypted, '8bit'),
'Message == decrypted' => $message === $trimDecrypted
]
);
但是,如果您将 $key
更改为值 "Quigibo"(与该值的 MD5 散列相反),则无法使用 OpenSSL 对加密值进行解码。
在与 OpenSSL 一起使用之前,是否有一种编码形式可以应用于 ASCII 密钥,以便正确解密值?
修改后的答案:
OpenSSL 中存在一个错误,它将 Blowfish 的密钥空填充到 16 个字节,这是不正确的,因为密码支持可变长度密钥。他们最近添加了一个标志来解决这个问题 - OPENSSL_DONT_ZERO_PAD_KEY - 但它仅在一周前发布的 php 7.1.8 中可用......相关错误:https://bugs.php.net/bug.php?id=72362
解决方法是手动循环密钥并将其输入 OpenSSL:
$keylen = (floor(mb_strlen($key, '8bit')/8)+1)*56;
$key_cycled = substr(str_repeat($key,ceil($keylen/strlen($key))),0,$keylen);
$decrypted = openssl_decrypt(
$encrypted,
'bf-ecb',
$key_cycled,
OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,
$iv
);
我需要能够使用 OpenSSL 解密在 PHP 下使用 Mcrypt 生成的值。
我有这个工作,除了用于加密它们的密钥是 ascii。
以下是我的代码,它演示了一个工作案例,当密钥是 MD5 时,OpenSSL 可以解密使用 Mcrypt 加密的值。
<?php
$message = 'test';
$key = md5('Quigibo');
$iv = openssl_random_pseudo_bytes(0);
$encrypted = mcrypt_encrypt(
MCRYPT_BLOWFISH,
$key,
$message,
MCRYPT_MODE_ECB,
$iv
);
$decrypted = openssl_decrypt(
$encrypted,
'bf-ecb',
$key,
OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,
$iv
);
$trimDecrypted = rtrim($decrypted);
var_export(
[
'Original message' => $message,
'Encrypted' => bin2hex($encrypted),
'Decrypted' => $decrypted,
'Trim decrypted' => $trimDecrypted,
'Message length' => mb_strlen($message, '8bit'),
'Decrypted length' => mb_strlen($decrypted, '8bit'),
'Message == decrypted' => $message === $trimDecrypted
]
);
但是,如果您将 $key
更改为值 "Quigibo"(与该值的 MD5 散列相反),则无法使用 OpenSSL 对加密值进行解码。
在与 OpenSSL 一起使用之前,是否有一种编码形式可以应用于 ASCII 密钥,以便正确解密值?
修改后的答案:
OpenSSL 中存在一个错误,它将 Blowfish 的密钥空填充到 16 个字节,这是不正确的,因为密码支持可变长度密钥。他们最近添加了一个标志来解决这个问题 - OPENSSL_DONT_ZERO_PAD_KEY - 但它仅在一周前发布的 php 7.1.8 中可用......相关错误:https://bugs.php.net/bug.php?id=72362
解决方法是手动循环密钥并将其输入 OpenSSL:
$keylen = (floor(mb_strlen($key, '8bit')/8)+1)*56;
$key_cycled = substr(str_repeat($key,ceil($keylen/strlen($key))),0,$keylen);
$decrypted = openssl_decrypt(
$encrypted,
'bf-ecb',
$key_cycled,
OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,
$iv
);