php – 使用Blowfish和ECB将mcrypt迁移到OpenSSL

我不能为我的生活弄清楚如何将我的传统mcrypt代码迁移到OpenSSL.我得到了CBC的Blowfish和CBC的Rijndael,但是欧洲央行的Blowfish正在躲避我.

是的,我读了Moving from mcrypt with Blowfish & ECB to OpenSSL,我尝试对数据进行零填充,而不是对数据进行零填充,对键进行零填充,在键上循环以及它们的任何组合,似乎没有任何效果.

这是我的代码

<?PHP
function encrypt_with_mcrypt($data, $key) {
        return mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_ECB);
}

function encrypt_with_openssl($data, $key) {
        return openssl_encrypt($data, 'BF-ECB', $key, OPENSSL_RAW_DATA | OPENSSL_DONT_ZERO_PAD_KEY);
}

$data = 'foobar';
$key = 'supersecretkey';

var_dump(base64_encode(encrypt_with_mcrypt($data, $key)));
var_dump(base64_encode(encrypt_with_openssl($data, $key)));

这是输出

test.PHP:13:
string(12) "5z0q3xNnokw="
test.PHP:14:
string(12) "1zyqavq7sCk="

解决方法:

mcrypt库/包装器认为零字节填充(仅在需要时),而OpenSSL库/包装器认为PKCS#5填充.这意味着单个块以不同方式填充,因此将显示不同的密文块.

一个常见的技巧是在没有任何取消填充的情况下解密生成的密文,然后通过查看十六进制中的明文填充来检查填充字节.

这将告诉你:

5z0q3xNnokw=
666f6f6261720000

对于mcrypt和

1zyqavq7sCk=
666f6f6261720202

对于OpenSSL.

使用需要加密多个块的较大明文消息也会向您显示除最后一个块之外加密正常.

当且仅当mcrypt输入不是8字节的倍数(Blowfish的块大小)时,首先对数据进行零填充,然后使用OPENSSL_ZERO_PADDING作为填充模式.

请注意,查看源代码显示OPENSSL_ZERO_PADDING出于某些未指定的原因似乎意味着包装器的“无填充”,并且OPENSSL_NO_PADDING似乎确实与其他设置冲突 – 我认为这是一个相当糟糕的设计和实现错误的开发人员PHP OpenSSL包装器API.

更多信息可以在the great research performed by Reinier找到,它显示了API如何填充/取消填充(或忘记填充/取消填充,具体取决于您的位置).

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...