LocalFree中断DPAPI加密/解密

时间:2019-05-17 15:58:47

标签: c++ windows encryption dpapi

我正在编写一个小型控制台程序,用于根据项目必须使用的约束条件来测试DPAPI(所有wstring,都需要在base64中输出加密的数据),并且遇到一个问题,如果我调用{{ 1}}在LocalFree输出Blob的pbData上,解密将失败。
我的CryptProtectDataEncrypt()助手:

Decrypt()

如果该行已被注释掉,然后调用std::wstring Encrypt(std::wstring input) { char *inputBuf = new char[input.size() + 1]; size_t temp = 0; wcstombs_s(&temp, inputBuf, input.size() + 1, input.c_str(), input.size()); CRYPT_INTEGER_BLOB inputBlob; inputBlob.cbData = strlen(inputBuf) + 1; inputBlob.pbData = (BYTE*)inputBuf; CRYPT_INTEGER_BLOB outputBlob; CryptProtectData(&inputBlob, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &outputBlob); BYTE *outputBlobPtr = (BYTE *)(&outputBlob); DWORD encodedLen = 0; CryptBinaryToStringW(outputBlobPtr, sizeof(CRYPT_INTEGER_BLOB), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &encodedLen); wchar_t *outputBuf = new wchar_t[encodedLen]; CryptBinaryToStringW(outputBlobPtr, sizeof(CRYPT_INTEGER_BLOB), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, outputBuf, &encodedLen); std::wstring output = std::wstring(outputBuf, encodedLen); LocalFree(outputBlob.pbData); // <-- This is the offending line delete[] inputBuf; delete[] outputBuf; return output; } std::wstring Decrypt(std::wstring input) { wchar_t *inputBuf = new wchar_t[input.size() + 1]; wcscpy_s(inputBuf, input.size() + 1, input.c_str()); DWORD decodedLen = 0; CryptStringToBinaryW(inputBuf, wcslen(inputBuf), CRYPT_STRING_BASE64, NULL, &decodedLen, NULL, NULL); BYTE *encryptedBlobPtr = new BYTE[decodedLen]; if (CryptStringToBinaryW(inputBuf, wcslen(inputBuf), CRYPT_STRING_BASE64, encryptedBlobPtr, &decodedLen, NULL, NULL) == 0) { std::cout << "String to blob conversion error: " << GetLastError() << std::endl; return std::wstring(); } CRYPT_INTEGER_BLOB encryptedBlob = *((CRYPT_INTEGER_BLOB *)encryptedBlobPtr); CRYPT_INTEGER_BLOB decryptedBlob; if (CryptUnprotectData(&encryptedBlob, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &decryptedBlob) == 0) { std::cout << "Decryption error: " << GetLastError() << std::endl; return std::wstring(); } wchar_t *outputBuf = new wchar_t[decryptedBlob.cbData + 1]; size_t temp = 0; mbstowcs_s(&temp, outputBuf, decryptedBlob.cbData + 1, (char *)decryptedBlob.pbData, decryptedBlob.cbData); std::wstring output = std::wstring(outputBuf, decryptedBlob.cbData + 1); LocalFree(decryptedBlob.pbData); delete[] inputBuf; delete[] encryptedBlobPtr; delete[] outputBuf; return output; } ,将结果存储在wstring中,然后调用Encrypt(L"Some string"),则会使我Decrypt(resultOfEncrypt)回来。如果该行在那里,则程序在"Some string"处以CryptUnprotectData()(无效数据)失败。
我是否误解了DPAPI或LocalFree()的工作方式?如果我已经通过将outputBlob转换为字符串来保存它,为什么它必须在内存中?

0 个答案:

没有答案