我正在编写一个小型控制台程序,用于根据项目必须使用的约束条件来测试DPAPI(所有wstring,都需要在base64中输出加密的数据),并且遇到一个问题,如果我调用{{ 1}}在LocalFree
输出Blob的pbData上,解密将失败。
我的CryptProtectData
和Encrypt()
助手:
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转换为字符串来保存它,为什么它必须在内存中?