【问题标题】:How to solve NTE_BAD_DATA using CryptDecrypt at final step如何在最后一步使用 CryptDecrypt 解决 NTE_BAD_DATA
【发布时间】:2020-06-30 20:56:46
【问题描述】:

我正在使用 WINAPI 使用 c++ 进行加密算法。我的加密工作完美无缺,我的解密也是如此,直到最后一个块用 final = TRUE 解密。我收到了 NTE_BAD_DATA 错误。

PS:我手动检查缓冲区,解密工作正常,直到最后一次 CryptDecrypt。

如果有人有想法,请帮助我:)

这是我的代码:

PVOID test(PVOID buffer, DWORD* length, PCHAR key_str2,bool isdecrypt) {
CHAR default_key[] = "3igcZhRdWq96m3GUmTAiv9";
CHAR* key_str = default_key;

size_t len = lstrlenA(key_str);

DWORD dwStatus = 0;
BOOL bResult = FALSE;
wchar_t info[] = L"Microsoft Enhanced RSA and AES Cryptographic Provider";
HCRYPTPROV hProv;
if (!CryptAcquireContextW(&hProv, NULL, info, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
    dwStatus = GetLastError();
    CryptReleaseContext(hProv, 0);
    return 0;
}
HCRYPTHASH hHash;
if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
    dwStatus = GetLastError();
    CryptReleaseContext(hProv, 0);
    return 0;
}

if (!CryptHashData(hHash, (BYTE*)key_str, len, 0)) {
    DWORD err = GetLastError();
    return 0;
}

HCRYPTKEY hKey;
if (!CryptDeriveKey(hProv, CALG_AES_128, hHash, 0, &hKey)) {
    dwStatus = GetLastError();
    CryptReleaseContext(hProv, 0);
    return 0;
}

const size_t chunk_size = CHUNK_SIZE;
BYTE chunk[chunk_size] = { 0 };
DWORD out_len = 0;

BOOL isFinal = FALSE;
DWORD readTotalSize = 0;

DWORD inputSize = *length;
PVOID newBuff = VirtualAlloc(0, inputSize, MEM_COMMIT, PAGE_READWRITE);
while (true)
{
    if (readTotalSize + chunk_size >= inputSize)
    {
        isFinal = TRUE;
        memcpy(chunk, PVOID((DWORD)buffer + readTotalSize), inputSize - readTotalSize);
        out_len = inputSize - readTotalSize;

    }
    else {
        memcpy(chunk, PVOID((DWORD)buffer + readTotalSize), chunk_size);
        out_len = chunk_size;
    }

    if (isdecrypt) {
        if (!CryptDecrypt(hKey, NULL, isFinal, 0, chunk, &out_len)) {
            int a = GetLastError();
            break;
        }
    }
    else {
        if (!CryptEncrypt(hKey, NULL, isFinal, 0, chunk, &out_len, chunk_size)) {
            break;
        }
    }
    if (readTotalSize + chunk_size >= inputSize) {
        memcpy(PVOID((DWORD)newBuff + readTotalSize), chunk, inputSize - readTotalSize);
        readTotalSize += inputSize - readTotalSize;
    }
    else {
        memcpy(PVOID((DWORD)newBuff + readTotalSize), chunk, chunk_size);
        readTotalSize += chunk_size;
    }

    if (isFinal)
        break;
    memset(chunk, 0, chunk_size);

}

CryptReleaseContext(hProv, 0);
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
return newBuff;

}

【问题讨论】:

    标签: c++ winapi cryptography


    【解决方案1】:

    您没有正确存储最后一个块的加密。

    您传递给加密的数据量在out_len 中,而被加密的数据量又放回到out_len 中。对于一个对整个块无关紧要的块密码,但您最后一个小于整个块的块被传递到加密可能会创建一个完整的加密数据块。

    这意味着您的加密数据可能比最终块中的纯文本稍大,但是当您解密时遇到问题,您不会努力处理这个问题,因为您丢失了一些加密数据在地板上。

    使用加密函数放入out_len 的值来存储您的数据(当您覆盖数据流时,您需要确保有空间)

    【讨论】:

      猜你喜欢
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-01
      • 2018-12-06
      相关资源
      最近更新 更多