【发布时间】:2011-05-02 10:37:17
【问题描述】:
之前我设法将一些 C++ CryptoPP Rijndael_128 CBC 代码移植到 MCrypt PHP,但现在我遇到了 CFB 模式的问题。 C++ 和 PHP 结果不匹配(第一个字节匹配,但这可能是巧合,其他一切都不匹配)。通过一些诊断,PHP 的 mcrypt 似乎没有正确设置密钥长度?
这是 C++(为简单起见,删除了诊断和杂项):
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_key 和 g_encrypt_iv 都是 16 字节长,并且字节匹配 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 对我的应用程序来说可能是多余的——我需要的最低要求是“对字节进行良好的加扰”,这样数据中各个字节的功能就不明显了。
【问题讨论】:
-
我注意到 mcrypt 的 OFB 和 NOFB 都报告了 32 字节的密钥大小(与 CFB 一样)。但是,如果我对 Crypto++ 使用 OFB_Mode 并为 mcrypt 使用 NOFB 模式,我会得到匹配的结果。这应该足以满足我的迫切需求,所以现在问题变成了一个学术问题:为什么密钥大小不同,为什么它们会产生不同的结果?
-
mcrypt 已损坏 - 提交错误报告。多年来一直如此,我不明白为什么这是一个反复出现的问题。多年来,我一直在回答 Crypto++ 的这类 mycrypt 问题。
标签: php c++ aes mcrypt crypto++