抛出异常:写入访问冲突。这是0xDDDDDDDD

时间:2016-09-20 05:03:46

标签: c++ aes access-violation crypto++

我正在尝试使用由Crypto ++库API 5.6.0版提供的AES加密来加密字符串,静态链接

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;
}

在函数出口我收到以下异常,同时尝试调用std :: string移动构造函数返回值:

  

抛出异常:写入访问冲突。这是0xDDDDDDDD。

看起来像StringSink“拥有”以某种方式返回std :: string并在尝试返回之前将其删除,但是我尝试将其分配给另一个std :: string并获得相同的异常。

返回任何其他字符串时出现相同的异常,因此看起来内存已损坏

1 个答案:

答案 0 :(得分:0)

StringSource(plain, true, 
    new StreamTransformationFilter(Encryptor,
        new HexEncoder(new StringSink(ciphertext_buffer))));

return ciphertext_buffer;

这段代码基本上没问题,但你应该避免使用匿名声明。

Exception thrown: write access violation. this was 0xDDDDDDDD.

0xDDDDDDDD is the "dead memory" bit pattern 代码存在很多问题,很难说是哪个问题导致你使用死记忆。也许PRIVATE_KEY小于32 * 2字节?

你应该做四件事:

  • 升级至Crypto++ 5.6.4(自2009年起为5.6.0)
  • 使用_CRTDBG_LEAK_CHECK_DF等标记启用内存检查(例如,请参阅test.cpp and main
  • 停止使用匿名声明(我已经看到析构函数因为它们而过早运行)
  • 使用EAX Mode中的Crypto++ wiki示例代码作为起点
// 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)));

使用Crypto ++ 5.6.3及更高版本中的HKDF

memset(iv, 0x00, AES::BLOCKSIZE);

我相信这会摧毁一些CBC的安全属性。您应该使用Authenticated Encryption模式。它可以减轻您的一些细节,例如生成随机IV。它还具有比单独使用CBC更好的安全性。