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?
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 ) )
)
);
And here's the 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
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).
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.
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?
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.
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.