2

好的,所以我有 5 个要加密的文件。我没有设置 IV。

第一个文件解密没问题,

那么剩余文件的第一个块不会被解密。

所以文件解密了 99%。


我尝试将 IV 设置为静态值和随机值,结果相同。

我加密的第一个文件不必是我解密的第一个文件,它可以 100% 解密。

这让我相信它与解密有关?


因此,对于加密,我导入了一个 aes 密钥来创建一个密钥句柄。

然后我加密一个文件并使用相同的密钥句柄移动到另一个文件......

我应该为每个文件都有一个新的密钥句柄吗..?

有清除钥匙柄的功能吗?


有什么东西告诉我 WCAPI 正在使用最后一个文件的最后一个块作为下一个文件的 IV?

如果我可能会误解某些东西,请原谅我。

这是decrypt_file函数:

DWORD dwMode = CRYPT_MODE_CBC;

LPVOID aes_key = NULL;
LPVOID tmp_blk_buff = NULL;
DWORD bytes_read = NULL;

BOOL eof = FALSE;

DWORD tmp_blk_buff_size = TMP_BLOCK_BUFFER_SIZE(context->in_size);

tmp_blk_buff = VirtualAlloc(0, tmp_blk_buff_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

Utils::zero_mem(tmp_blk_buff, tmp_blk_buff_size);

LPVOID iv_ = NULL;
iv_ = VirtualAlloc(0, AES_BLOCK_SIZE_, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
Utils::zero_mem(iv_, AES_BLOCK_SIZE_);

/*BYTE iv[AES_BLOCK_SIZE_] = {
    0xAD, 0xAD, 0xAD, 0xAD,
    0xAD, 0xAD, 0xAD, 0xAD,
    0xAD, 0xAD, 0xAD, 0xAD,
    0xAD, 0xAD, 0xAD, 0xAD
};
*/
//  Utils::copy_mem(iv_, AES_BLOCK_SIZE_, iv, AES_BLOCK_SIZE_);


//CryptSetKeyParam(context->aes_hKey, KP_IV, (BYTE*)&iv_, 0);

CryptSetKeyParam(context->aes_hKey, KP_MODE, (BYTE*)&dwMode, 0);

// Encrypt data
do{
    Utils::zero_mem(tmp_blk_buff, tmp_blk_buff_size);
    bytes_read = NULL;

    ReadFile(hFile_in, tmp_blk_buff, AES_BLOCK_SIZE_, &bytes_read, NULL);

    if (bytes_read < AES_BLOCK_SIZE_)
    {
        eof = TRUE;
    }

    if (!CryptDecrypt(context->aes_hKey, NULL, eof, 0,(LPBYTE)tmp_blk_buff, &bytes_read))
    {
        context->last_error = GetLastError();

        eof = TRUE;
    }

    WriteFile(hFile_out, tmp_blk_buff, bytes_read, &bytes_read, NULL);

} while (!eof);

// ===============
//  Zero and Free Allocated memory.
Utils::zero_mem(tmp_blk_buff, tmp_blk_buff_size);
VirtualFree(tmp_blk_buff, tmp_blk_buff_size, MEM_RELEASE);

return (DWORD)1;
4

2 回答 2

0

我使用 CryptDuplicateKey 和适当的 DestroyKey 调用,解决了我的问题。

使用复制的键设置参数,保持原键不变。

于 2015-09-13T21:00:14.020 回答
0

是的,这表明您在给定的加密/解密对上获得了不同的 IV。

只有第一个块被“损坏”的原因是 CBC 块错误只传播到下一个块(而不是进一步传播)。

您要么从先前的操作链接(如果您要跨文件重用上下文),要么您没有将上下文初始化为加密和解密的相同值。

查看您的代码,您已注释掉CryptSetKeyParam(....,KP_IV,....),这意味着您的 AES 上下文可能在 IV 中有未知数据。

一个相对常见的做法是始终使用 0 作为 IV,但在数据的开头放置一个随机“盐”块。然后在解密时忽略第一个数据块。它只是用来随机化数据。

或者,您可以随机化 IV,但将其以纯文本形式发送到加密消息中。这也很常见。

或者您可以在加密时随机化 IV,在真实消息之前放入一个随机数据块。在解密时使用任何 IV 并丢弃第一个块(因为它将是垃圾)。

这几乎是相同的结果(您最终会传输 16 个字节作为开销),但您应该在您的消息中添加一些随机性(通过 IV 或第一个块)以阻止捷径攻击。

于 2015-09-12T04:02:00.630 回答