当PHP CryptoPP AES加密到PHP的mcrypt时,PHP mcrypt中的键大小不正确 [英] Incorrect key size in PHP mcrypt when porting CryptoPP AES encryption to PHP's mcrypt

查看:326
本文介绍了当PHP CryptoPP AES加密到PHP的mcrypt时,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):

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

//  CryptoPP::AES::DEFAULT_KEYLENGTH has the value of 16

// The HexEncoder is being used for debugging purposes, product code uses Base32

CryptoPP::StringSource( sInput.c_str(), true, 
        new CryptoPP::StreamTransformationFilter( encryptor, 
        new CryptoPP::HexEncoder( new CryptoPP::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_key g_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.

我认为问题是,keysize是报告为32字节。看看mcrypt文档,设置keysize的唯一方法是提供所需大小的密钥。但我传递一个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.

推荐答案

这是已经有一段时间了,但我有一些类似的问题,mcrypt和openSSL使用CFB几年前。最后,我发现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 强制反馈链等于算法的块大小,在这种情况下是AES128(Rijndael)的128位块/反馈,它与 manpage 为mcrypt模块状态关于nOFB。这是好的,因为一切我发现说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和任何其他AES库在CBC或nOFB。这不会是如果mcrypt填充我的128位(16字符)键与额外的128位空字符串,或任何,并不会在技术上是正确的。

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.

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

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