移植Crypto+;时密钥大小不正确+;AES加密到PHP';s mcrypt 早些时候,我设法将C++ CypTopp RijnDael128 CBC代码移植到McLIPT PHP,但现在我遇到CFB模式的问题。C++和PHP结果不匹配(第一个字节匹配,但这可能是巧合,其他的都不匹配)。通过一些诊断,PHP的mcrypt似乎没有正确设置密钥长度 这里是C++(简单的诊断和杂项):< /P> CFB\u模式::加密加密器(g\u加密密钥,AES::默认密钥长度,g\u加密密钥iv); StringSource ss(sInput.c_str(),true, 新的StreamTransformationFilter(加密机、, 新的HexEncoder(新的StringSink(sEncryptedOut)) ));

移植Crypto+;时密钥大小不正确+;AES加密到PHP';s mcrypt 早些时候,我设法将C++ CypTopp RijnDael128 CBC代码移植到McLIPT PHP,但现在我遇到CFB模式的问题。C++和PHP结果不匹配(第一个字节匹配,但这可能是巧合,其他的都不匹配)。通过一些诊断,PHP的mcrypt似乎没有正确设置密钥长度 这里是C++(简单的诊断和杂项):< /P> CFB\u模式::加密加密器(g\u加密密钥,AES::默认密钥长度,g\u加密密钥iv); StringSource ss(sInput.c_str(),true, 新的StreamTransformationFilter(加密机、, 新的HexEncoder(新的StringSink(sEncryptedOut)) ));,php,c++,aes,mcrypt,crypto++,Php,C++,Aes,Mcrypt,Crypto++,下面是PHP: $cipher=mcrypt_模块_打开(mcrypt_RIJNDAEL_128',mcrypt_模式_CFB',) mcrypt_generic_init($cipher,$g_encrypt_key,$g_encrypt_iv); $sEncryptedOutput=mcrypt_generic($cipher,$sInput); mcrypt_generic_deinit($cipher); mcrypt_模块_close($cipher); 代码> GyBufftTyK

下面是PHP:

$cipher=mcrypt_模块_打开(mcrypt_RIJNDAEL_128',mcrypt_模式_CFB',)
mcrypt_generic_init($cipher,$g_encrypt_key,$g_encrypt_iv);
$sEncryptedOutput=mcrypt_generic($cipher,$sInput);
mcrypt_generic_deinit($cipher);
mcrypt_模块_close($cipher);

代码> GyBufftTyKEY < /C> >代码> GyBuffTyIV两个字节长,字节与C++和PHP版本匹配。对于PHP版本,它是一个由字节构成的二进制字符串(是的,我已经检查过这些字节是相同的)

我在PHP版本中添加了检查
$cipher
的块大小、密钥大小等的调用。 块大小和iv大小均为16;支持的密钥大小报告为16、24和32-所有这些都与预期的一样

我认为问题在于,密钥大小被报告为32字节。查看mcrypt文档,设置密钥大小的唯一方法是提供所需大小的密钥。但我正在传递一个16字节的密钥!那么为什么它报告存在32字节的密钥呢?如果CFB模式必须使用32字节的密钥,那么为什么CryptoPP会接受它?解决办法是什么?我可以强制PHP使用已经提供的16字节密钥吗?或者是否有一个我缺少的参数,它在CryptoPP中的默认设置与在MCrypt中的不同

我使用CFB模式是因为我希望最小化生成的加密数据的长度。填充将引入的几个字节在这个应用程序中很重要


我需要能够在C++中加密/解密,但只在PHP中加密。AES对我的应用程序来说无疑是杀伤力过大——我需要的最低要求是“对字节进行良好的置乱”,这样数据中单个字节的功能就不明显了。

这已经有一段时间了,但几年前我在使用CFB的mcrypt和openSSL中遇到了一些类似的问题。最后,我发现mcrypt使用的默认反馈链大小与CFB模式下的openssl不同。也就是说,我相信CFB中的openSSL AES128使用了128位的块大小和反馈大小,而mcrypt使用了128位的块大小和8位的反馈大小。我没有办法证实这一点,这只是当时阅读一些旧论坛帖子的猜测。不管这个理论的真实性如何,我不是唯一一个或第一个有这个问题的人

对我来说,解决办法是把nOFB当作你自己。根据
MCRYPT_MODE_NOFB
强制反馈链等于算法的块大小,在这种情况下,AES128(Rijndael)的128位块/反馈与MCRYPT模块关于NOFB的状态相匹配。这是好的,因为我发现的所有东西都说nOFB反馈与块大小同步。因此,nOFB中的mcrypt和OpenSSL现在都是AES128的128位密钥/iv/块/反馈大小,一切正常

就PHP报告的256位密钥大小(32字节)而言,返回当前密码算法密钥大小的函数实际上返回最大密钥大小,这在文档中没有明确说明。我之所以知道这一点,是因为我现在一直在各种项目中使用的小类与openSSL以及CBC或nOFB中的任何其他AES库一起工作得非常好。如果mcrypt在我的128位(16个字符)的密钥中添加了一个128位的空字符串,或者其他什么,那么情况就不会是这样,而且从技术上讲也不正确

这不是一个很好的答案,但我得到的最好答案是基于几年前对密码学的一次非常业余的尝试。

查看phpseclib:

可以将键大小和块大小设置为所需的任何值


例如$aes->setKeyLength(128)或$aes->setKeyLength(256)

我遇到了这个问题——几点。默认情况下,PHP Rijndael模式将反馈循环设置为8位,即AES的长度必须与IV/键的长度相同

您可以通过使用模式“ncfb”而不是“cfb”或MCRYPT_mode_cfb来实现这一点

有关编写aes_cfb_128兼容PHP的完整详细信息,请参见此安全堆栈交换问题:。它的简称是(来自Tom Leek):

。。。对于CFB和OFB(它们彼此不同,不能互换使用),您必须担心“反馈长度”,这不一定在各种加密库中以高清晰度记录。加密和解密必须使用相同的反馈长度才能进行互操作


我注意到mcrypt的OFB和NOFB都报告了32字节的密钥大小(与CFB一样)。然而,如果我对Crypto++使用OFB_模式,对mcrypt使用NOFB模式,我会得到匹配的结果。这应该足以满足我当前的需要,所以现在的问题变成了一个学术性的问题:为什么键大小不同,为什么它们产生不同的结果?mcrypt被打破了-提交一份错误报告。多年来一直如此,我不明白为什么这是一个反复出现的问题。多年来,我一直在用Crypto++解答这些类型的mycrypt问题,所以这不仅仅是我自己。我想知道反馈的大小,但找不到查询或更改的方法。PHP的mcrypt库实际上有两种查询密钥大小的方法。是的,我找到了你描述的方法。另一种仅基于算法和块模式,而不是提供的k