I have a c++ application that encrypts a text using the following code:
– Set default AES values:
void Utl_Cryptopp::aes_SetDefaultCryptoppKey()
{
if (mAES_IsSetCryptoppKey)
{
return;
}
if (mAES_CryptoppKey.size() || mAES_CryptoppIV.size())
{
mAES_CryptoppKey.clear();
mAES_CryptoppKey.resize(CryptoPP::AES::DEFAULT_KEYLENGTH);
mAES_CryptoppIV.clear();
mAES_CryptoppIV.resize(CryptoPP::AES::DEFAULT_KEYLENGTH);
}
mAES_CryptoppKey = { /* Array Of Characters - KEY */ };
mAES_CryptoppIV = { /* Array Of Characters - IV */ };
CryptoPP::SecByteBlock mCryptoppKey(CryptoPP::AES::BLOCKSIZE);
CryptoPP::SecByteBlock mCryptoppIV(CryptoPP::AES::BLOCKSIZE);
mCryptoppKey = CryptoPP::SecByteBlock(reinterpret_cast< const CryptoPP::byte* >(mCryptoppKey.data()), CryptoPP::AES::BLOCKSIZE);
mCryptoppIV = CryptoPP::SecByteBlock(reinterpret_cast< const CryptoPP::byte* >(mCryptoppIV.data()), CryptoPP::AES::BLOCKSIZE);
mAES_Encryption = CryptoPP::AES::Encryption(mAES_CryptoppKey.data(), mAES_CryptoppKey.size());
mAES_CBC_Encryption = CryptoPP::CBC_Mode_ExternalCipher::Encryption(mAES_Encryption, mAES_CryptoppIV.data());
mAES_Decryption = CryptoPP::AES::Decryption(mAES_CryptoppKey.data(), mAES_CryptoppKey.size());
mAES_CBC_Decryption = CryptoPP::CBC_Mode_ExternalCipher::Decryption(mAES_Decryption, mAES_CryptoppIV.data());
mAES_IsSetCryptoppKey = true;
}
– Then the C++ code that encrypts:
bool Utl_Cryptopp :: aes_Encrypt(const Gfc_String &aPlainText, Gfc_String &aCipherText)
{
try
{
if (!aes_IsSetCryptoppKey())
{
aes_SetDefaultCryptoppKey();
}
CryptoPP::StringSource lStringSource(aPlainText, true, new CryptoPP::StreamTransformationFilter(mAES_CBC_Encryption, new CryptoPP::Base64Encoder(new CryptoPP::StringSink(aCipherText))));
return true;
}
catch (const CryptoPP::Exception &aExeption)
{
std::cerr << aExeption.what() << std::endl;
}
return false;
}
– Then my C# that tries to decrypt following the documentation here:
private string decryptAES(string aInput)
{
string plaintext = null;
byte[] lInputBytes = Encoding.ASCII.GetBytes(aInput);
byte[] lAES_CryptoppKey = Encoding.UTF8.GetBytes(/* Same KEY as above but as string */);
byte[] lAES_CryptoppIV = Encoding.UTF8.GetBytes(/* Same IV as above but as string */);
// Create AesManaged
using (AesManaged aes = new AesManaged())
{
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.Zeros;
aes.Key = lAES_CryptoppKey;
aes.IV = lAES_CryptoppIV;
// Create a decryptor
ICryptoTransform decryptor = aes.CreateDecryptor(lAES_CryptoppKey, lAES_CryptoppIV);
// Create the streams used for decryption.
using (MemoryStream lMemoryStream = new MemoryStream(lInputBytes))
{
// Create crypto stream
using (CryptoStream lCryptoStream = new CryptoStream(lMemoryStream, decryptor, CryptoStreamMode.Read))
{
// Read crypto stream
using (StreamReader lStreamReader = new StreamReader(lCryptoStream))
{
try
{
plaintext = lStreamReader.ReadToEnd();
}
catch (Exception e)
{ }
}
}
}
}
return plaintext;
}
But the C# code will throw:
I tried manually padding the input with zeros up to multiple of 16s (block size):
byte[] lOrigInputBytes = Encoding.ASCII.GetBytes(aInput);
byte[] lInputBytes = lOrigInputBytes;
if (lOrigInputBytes.Length % 16 != 0)
{
// get existing number of blocks
var lBlocksCount = lOrigInputBytes.Length / 16;
// reinitialize (this will pad the rest with 0s)
lInputBytes = new byte[(lBlocksCount + 1) * 16];
// copy existing
for (int i = 0; i < lOrigInputBytes.Length; ++i)
{
lInputBytes[i] = lOrigInputBytes[i];
}
}
But now I start getting garbage output:
I looked at these similar Qs but with no success:
- the input data is not a complete block. AES decryption
- AES decryption error ” The input data is not a complete block.” Error vb.net
- Error “The input data is not a complete block” while Decrypt in MVC
- AES-128-ECB decryption: The input data is not a complete block
Any ideas what am I doing wrong? Thanks in advance I really appreciate it!