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

Exception thrown: write access violation. this was 0xDDDDDDDD

我正在尝试使用 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 移动构造函数到 return 值:

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

看起来像 StringSink "owns" returned std::string 并在尝试 return 之前将其删除,但我试图将其分配给另一个 std::string 并得到相同的异常。

在 return 任何其他字符串时出现相同的异常,因此似乎内存以某种方式损坏

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(5.6.0 来自 2009)
  • 使用 _CRTDBG_LEAK_CHECK_DF 等标志打开内存检查(示例参见 test.cpp and main
  • 停止使用匿名声明(我看到析构函数 运行 太早了,因为它们)
  • 使用EAX Mode sample code from the 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 更好的安全属性。