c++ - 如何在最后一步使用 CryptDecrypt 解决 NTE_BAD_DATA
问题描述
我正在使用 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;
}
解决方案
您没有正确存储最终块的加密。
您传递到加密的数据量在out_len
,加密的数据量被放回out_len
。对于一个对整个块无关紧要的块密码,但是你的最后一个小于整个块的块被传递到加密可能会创建一个完整的加密数据块。
这意味着您的加密数据可能比最终块中的纯文本大一点,但是当您解密时遇到问题,您不会努力处理这个问题,因为您将一些加密数据丢弃在地板上.
使用out_len
加密函数输入的值来存储您的数据(当您覆盖数据流时,您需要确保有空间)
推荐阅读
- directory - 如何通过ansible检查多个目录中的777权限
- android - 如何将未标记的 UI 元素扩展为对讲的图标?
- oracle - 当我尝试打开由 Oracle 外部表写入的 .log 和 .bad 文件时,我得到拒绝访问
- python - 我在用 python 编写的阶乘程序中遇到错误
- qt - 在 eventFilter 中绘制事件后无法清除 QLabel 内容
- django - Django:访问不同服务器上的数据库:“fastCGI 进程超出了配置的活动超时”
- django - 如何在 wagtail cms 2.13.x 中呈现 FieldBlock?
- unity3d - 使 Gameobject 独立上下浮动帧速率(2D)
- json - 如何使用 serde 反序列化具有泛型类型的枚举
- node.js - Node.js、Sequelize、mysql 和 Vue 的日期格式