I'm trying to encrypt a string using AES encryption provided by Crypto++ library API, version 5.6.0, linked statically
string AESEncryptor::encrypt(const string& plain)
{
string ciphertext_buffer;
// Hex decode symmetric key:
HexDecoder decoder;
decoder.Put((byte *)PRIVATE_KEY, 32 * 2);
decoder.MessageEnd();
word64 size = decoder.MaxRetrievable();
char *decoded_key = new char[size];
decoder.Get(reinterpret_cast<byte*>(decoded_key), size);
// Generate Cipher, Key, and CBC
byte key[AES::MAX_KEYLENGTH], iv[AES::BLOCKSIZE];
StringSource(reinterpret_cast<const char *>(decoded_key), true,
new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH)));
memset(iv, 0x00, AES::BLOCKSIZE);
CBC_Mode<AES>::Encryption Encryptor(key, sizeof(key), iv);
StringSource(plain, true,
new StreamTransformationFilter(Encryptor, new HexEncoder(new StringSink(ciphertext_buffer))));
return ciphertext_buffer;
}
On the function exit I'm receiving the following exception, while trying to call the std::string move constructor to return the value:
Exception thrown: write access violation. this was 0xDDDDDDDD.
Looked like StringSink "owns" returned std::string some way and deletes it before trying to return, however I tried to assign it to another std::string and got the same exception.
Same exception appears while returning any other string, so it seems memory corrupted some way
StringSource(plain, true, new StreamTransformationFilter(Encryptor, new HexEncoder(new StringSink(ciphertext_buffer)))); return ciphertext_buffer;
This code is mostly OK, but you should avoid the anonymous declarations.
Exception thrown: write access violation. this was 0xDDDDDDDD.
0xDDDDDDDD is the "dead memory" bit pattern
There's quite a few issues with the code, and its hard to say which is causing you to use the dead memory. Maybe PRIVATE_KEY
is smaller than 32 * 2
bytes?
You should do four things:
_CRTDBG_LEAK_CHECK_DF
(see test.cpp
and main
for an example)// Generate Cipher, Key, and CBC byte key[AES::MAX_KEYLENGTH], iv[AES::BLOCKSIZE]; StringSource(reinterpret_cast<const char *>(decoded_key), true, new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH)));
Use HKDF from Crypto++ 5.6.3 and above.
memset(iv, 0x00, AES::BLOCKSIZE);
I believe this destroys some of CBC's security properties. You should use an Authenticated Encryption mode. It relieves you of some of the details, like generating random IVs. It also has better security properties than CBC alone.