将Crypto ++ AES加密移植到PHP的mcrypt时,密钥大小不正确 [英] Incorrect key size when porting Crypto++ AES encryption to PHP's mcrypt

查看:165
本文介绍了将Crypto ++ AES加密移植到PHP的mcrypt时,密钥大小不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

之前,我设法将一些C ++ CryptoPP Rijndael_128 CBC代码移植到MCrypt PHP,但是现在我在CFB模式下遇到了问题. C ++和PHP结果不匹配(很好的是第一个字节匹配,但这可能是巧合,其他所有都不是).经过一些诊断,看来PHP的mcrypt没有正确设置密钥长度?

Earlier I managed to port some C++ CryptoPP Rijndael_128 CBC code to MCrypt PHP, but now I'm having problems with CFB mode. The C++ and PHP results do not match (well the first byte matches but this could be coincidence, everything else doesn't). With some diagnostics, it looks like PHP's mcrypt is not setting the key length correctly?

这里是C ++(为简单起见,删除了诊断和杂物):

Here's the C++ (diagnostics and sundries removed for simplicity):

CFB_Mode<AES>::Encryption encryptor(g_encrypt_key, AES::DEFAULT_KEYLENGTH, g_encrypt_iv);

StringSource ss( sInput.c_str(), true, 
        new StreamTransformationFilter( encryptor, 
            new HexEncoder( new StringSink( sEncryptedOut ) )
        ));

这是PHP:

$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CFB, '')
mcrypt_generic_init($cipher, $g_encrypt_key, $g_encrypt_iv);

$sEncryptedOutput = mcrypt_generic( $cipher, $sInput);
mcrypt_generic_deinit($cipher);
mcrypt_module_close($cipher);

g_encrypt_keyg_encrypt_iv均为16个字节长,并且这些字节与C ++和PHP版本匹配.对于PHP版本,它是由字节构成的二进制字符串(是的,我已经检查过它们是否相同).

g_encrypt_key and g_encrypt_iv are both 16 bytes long, and the bytes match for the C++ and PHP versions. For the PHP version it is a binary string constructed from the bytes (yes I have checked these are identical).

我已经添加了对PHP版本的调用,以检查$cipher的块大小,密钥大小等. 块大小和iv大小均为16;支持的密钥大小报告为16、24和32,均与预期一致.

I have added calls to the PHP version to check $cipher's block size, key size, etc. The block size and iv size are both 16; supported key sizes are reported as 16, 24, and 32 - all as expected.

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

Where I think the problem is, is that the keysize is being reported as 32 bytes. Looking at the mcrypt docs, the only way of setting the keysize is by supplying a key of the required size. But I'm passing a 16 byte key! So why is it reporting the presence of a 32 byte key? If CFB mode must use a 32 byte key, then why does CryptoPP accept it as okay? What is the solution? Can I force PHP to use the 16 byte key that has been provided? Or is there a parameter that I'm missing which is defaulting to a different setting in CryptoPP than in MCrypt?

我使用CFB模式是因为我想最小化生成的加密数据的长度.在本应用程序中,填充会引入的几个字节确实很重要.

I am using the CFB mode because I want to minimize the length of the resulting encrypted data. The few bytes that padding would introduce, do matter in this application.

我需要能够在C ++中进行加密/解密,但只能在PHP中进行加密. AES对于我的应用程序可以说是过大了-我需要的最低要求是对字节进行良好的加扰",以使数据中各个字节的功能不明显.

I need to be able to encrypt/decrypt in C++ but only encrypt in PHP. AES is arguably overkill for my application - the minimum I need is "a good scrambling of the bytes" so that the function of individual bytes in the data are not obvious.

推荐答案

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

It's been awhile, but I had some similar problems with mcrypt and openSSL using CFB a couple years ago. In the end, I discovered mcrypt used a different default feedback chain size than openssl in CFB mode. That is to say, I believe an openSSL AES128 in CFB used a block size and feedback size of 128 bits, while mcrypt used a block size of 128bits and a feedback size of 8 bits. I have no way to confirm this, it was just speculation at the time based on reading some old forum posts. Regardless of the truth of that theory, I was not the only person or first to have this particular issue.

对我来说,解决方案是使用nOFB作为自己.根据 PHP mcrypt库参考 MCRYPT_MODE_NOFB强制进行反馈-chain等于算法的块大小,在这种情况下为AES128(Rijndael)的128位块/反馈,它与 用于有关nOFB的mcrypt模块状态.很好,因为我发现所有内容都表明nOFB反馈与块大小同步.因此,nOFB中的mcrypt和OpenSSL现在都是AES128的128位密钥/iv/块/反馈大小,并且一切正常.

The solution for me was to use nOFB as yourself. According to the PHP mcrypt library reference MCRYPT_MODE_NOFB forces the feedback-chain to equal the algorithm's block size, in this case a 128bit block/feedback for AES128 (Rijndael), which matches with what the manpage for the mcrypt module states about nOFB. This is good as everything I found said nOFB feedback is synchronous to the block size. Thus, both mcrypt and OpenSSL in nOFB were now 128 bit key/iv/block/feedback sizes for AES128 and everything worked fine.

就PHP报告256位密钥大小(32字节)而言,返回当前密码算法密钥大小的函数实际上将返回最大密钥大小,该大小在文档中并未明确说明.我知道这一点是因为我一直在各种项目中使用的我的小班级在openSSL和CBC或nOFB中的任何其他AES库中都可以正常工作.如果mcrypt在我的128bit(16 char)密钥上填充了额外的128bits的null字符串或其他内容,就不会是这种情况,并且无论如何在技术上都不正确.

As far as PHP reporting 256bit keysizes (32 bytes), the function that returns the current cipher-algorithm key size actually returns the maximum key size, which isn't clearly stated in the documentation. I know this because my little class I use all the time now for various projects works perfectly fine with openSSL and any other AES libraries in CBC or nOFB . This wouldn't be the case if mcrypt was padding my 128bit(16 char) key with an additional 128bits of null string, or whatever, and wouldn't be technically correct anyhow.

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

Not really a good answer, but the best I got based on a very amateurish foray into cryptography several years ago.

这篇关于将Crypto ++ AES加密移植到PHP的mcrypt时,密钥大小不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆