使用Blowfish和ECB将mcrypt迁移到OpenSSL [英] Migrating mcrypt with Blowfish and ECB to OpenSSL
问题描述
我一辈子都想不通如何将旧的mcrypt代码迁移到OpenSSL.我在CBC的Blowfish和CBC的Rijndael都可以使用它,但是在ECB的Blowfish却让我望而却步.
I can't for the life of me figure out how to migrate my legacy mcrypt code to OpenSSL. I got it working for Blowfish with CBC and for Rijndael with CBC, but Blowfish with ECB is eluding me.
是的,我读了使用Blowfish和Amp从mcrypt移动.从ECB到OpenSSL ,我尝试对数据进行零填充,不对数据进行零填充,对密钥进行零填充,对密钥进行循环以及它们的任何组合,但似乎没有任何效果.
And yes, I read Moving from mcrypt with Blowfish & ECB to OpenSSL and I tried zero-padding the data, not zero-padding the data, zero-padding the key, cycling over the key and any combination of them and nothing seems to work.
这是我的代码:
<?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填充.这意味着单个块的填充方式不同,因此将显示不同的密文块.
The mcrypt library / wrapper defaults to zero-byte padding (only when required) while OpenSSL library / wrapper defaults to PKCS#5 padding. That means that the single block gets padded differently and will therefore show a different block of ciphertext.
一个常见的技巧是解密得到的密文而没有进行任何填充,然后通过查看十六进制的明文+填充来检查填充字节.
A common trick is to decrypt the resulting ciphertext without any unpadding and then check the padding bytes by viewing the plaintext + padding in hexadecimals.
这将向您显示
5z0q3xNnokw=
666f6f6261720000
用于mcrypt和
1zyqavq7sCk=
666f6f6261720202
用于OpenSSL.
使用较大的纯文本消息,要求对多个块进行加密,这也会向您显示,对于最后一个块,除 之外,加密进行得很好.
Using a larger plaintext message that requires multiple blocks to be encrypted would also have shown you that encryption is going fine except for the last block.
首先且仅当mcrypt输入不是8字节(Blowfish的块大小)的倍数时,才对数据进行零填充.然后,将OPENSSL_ZERO_PADDING
用作填充模式.
First zero-pad your data if and only if the mcrypt input is not a multiple of 8 bytes (the block size of Blowfish), then use OPENSSL_ZERO_PADDING
as the padding mode.
请注意,查看源代码表明,出于某些未指定原因,OPENSSL_ZERO_PADDING
似乎意味着包装程序无填充",而OPENSSL_NO_PADDING
似乎与其他设置冲突-我认为这是一个相当糟糕的设计, PHP OpenSSL包装器API的开发人员实施错误.
Note that looking at the source code shows that OPENSSL_ZERO_PADDING
for some unspecified reason seems to mean "no padding" for the wrapper and OPENSSL_NO_PADDING
does seem to conflict with other settings - this I regard as a rather bad design and implementation mistake by the developers of the PHP OpenSSL wrapper API.
更多信息可以在 Reinier进行的出色研究中找到,该研究表明了API如何填充(或遗忘)垫/解垫,具体取决于您的站立位置.
More info can be found by the great research performed by Reinier that shows how the API pads / unpads (or forgets to pad / unpad, depending on where you stand).
这篇关于使用Blowfish和ECB将mcrypt迁移到OpenSSL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!