Reputation: 7174
I am trying to decrypt data using AES CBC and CTR mode. The ciphertext has been prepended with the 16 byte IV.
I have my ciphertext data in the following format:
vector<vector<byte>> CBCMessages;
vector<vector<byte>> CBCKeys;
vector<vector<byte>> CTRMessages;
vector<vector<byte>> CTRKeys;
I am using Crypto++ to decrypt the data. This is my code:
for (int i = 0; i < CBCMessages.size(); i++)
{
std::string decryptedtext;
// split IV from ciphertext
byte iv[16];
std::copy(CBCMessages[i].begin(), CBCMessages[i].begin()+16, iv);
CBCMessages[i].erase(CBCMessages[i].begin(), CBCMessages[i].begin()+16);
// this block works fine
AES::Decryption aesDecryption(&(CBCKeys[i][0]), CBCKeys[i].size());
CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );
StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedtext ) );
stfDecryptor.Put( reinterpret_cast<const unsigned char*>( &(CBCMessages[i][0]) ), CBCMessages[i].size() );
stfDecryptor.MessageEnd();
std::cout << decryptedtext << std::endl;
}
for (int i = 0; i < CTRMessages.size(); i++)
{
std::string decryptedtext;
// split IV from ciphertext
byte iv[16];
std::copy(CTRMessages[i].begin(), CTRMessages[i].begin()+16, iv);
CTRMessages[i].erase(CTRMessages[i].begin(), CTRMessages[i].begin()+16);
// this block produces junk
AES::Decryption aesDecryption(&(CTRKeys[i][0]), CTRKeys[i].size());
CTR_Mode_ExternalCipher::Decryption ctrDecryption( aesDecryption, iv );
StreamTransformationFilter stfDecryptor(ctrDecryption, new CryptoPP::StringSink( decryptedtext ) );
stfDecryptor.Put( reinterpret_cast<const unsigned char*>( &(CTRMessages[i][0]) ), CTRMessages[i].size() );
stfDecryptor.MessageEnd();
std::cout << decryptedtext << std::endl;
// try again with different method - this works fine
decryptedtext.clear();
CTR_Mode< AES >::Decryption d;
d.SetKeyWithIV( &(CTRKeys[i][0]), CTRKeys[i].size(), iv, 16 );
StringSource( reinterpret_cast<const unsigned char*>( &(CTRMessages[i][0]) ), CTRMessages[i].size(), true,
new StreamTransformationFilter( d,
new StringSink( decryptedtext )
)
);
std::cout << decryptedtext << std::endl;
}
As you can see, the middle block (first block for CTR decryption) produces junk output. Note that this block should actually be pretty identical to the block used for CBC decryption.
The block used for CBC decryption is basically copied from this FAQ entry (answer by 2005-Oct-21 10:38am jeffrey). I have then altered this block to use it for CTR decryption which is when it failed to work. The second CTR block is inspired by the "Sample Program" section here.
What seems to be the problem in the first CTR code block?
Upvotes: 2
Views: 763
Reputation: 14731
It is probably because
AES::Decryption aesDecryption(&(CTRKeys[i][0]), CTRKeys[i].size());
https://upload.wikimedia.org/wikipedia/commons/3/3c/CTR_decryption_2.svg
CTR Mode needs AES::Encryption to decrypt the ciphertest
https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
Upvotes: 3