早些时候,我设法将一些 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
and 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 对于我的应用程序来说可以说是杀伤力过大 - 我需要的最低限度是“对字节进行良好的加扰”,以便数据中各个字节的功能不明显。