使用CryptUnprotectData函数遇错误码87(无效参数)问题求助
问题分析与解决:CryptUnprotectData错误码87(无效参数)
问题核心
你直接将普通字符串传入CryptUnprotectData,但该函数仅能解密由CryptProtectData生成的加密二进制数据,普通文本不是合法的加密格式,这直接导致了错误码87(无效参数)。
错误点拆解
- 代码中
data是普通字符串,并非CryptProtectData输出的加密Blob,不符合函数的输入要求。 - 使用
strlen计算长度不适用于二进制加密数据(加密数据可能包含\0),正确做法是直接使用字符串的字节长度。
修正后的代码
#include <windows.h> #include <Wincrypt.h> #include <string> #include <iostream> using namespace std; #pragma comment(lib, "crypt32.lib") int main() { // 原始明文数据 wstring plainData = L"data I want to encrypt then decrypt"; wcout << L"原始明文: " << plainData << endl; // 1. 先使用CryptProtectData加密数据,生成合法的加密Blob DATA_BLOB dataIn; dataIn.pbData = reinterpret_cast<BYTE*>(const_cast<wchar_t*>(plainData.c_str())); dataIn.cbData = plainData.size() * sizeof(wchar_t); DATA_BLOB dataEncrypted; if (!CryptProtectData(&dataIn, L"Test Description", NULL, NULL, NULL, 0, &dataEncrypted)) { wcout << L"加密失败,错误码: " << GetLastError() << endl; return 1; } wcout << L"加密完成,准备解密..." << endl; // 2. 使用CryptUnprotectData解密加密后的Blob DATA_BLOB dataDecrypted; LPWSTR descOut = NULL; if (CryptUnprotectData(&dataEncrypted, &descOut, NULL, NULL, NULL, 0, &dataDecrypted)) { wstring decryptedStr(reinterpret_cast<wchar_t*>(dataDecrypted.pbData), dataDecrypted.cbData / sizeof(wchar_t)); wcout << L"解密结果: " << decryptedStr << endl; // 释放内存 LocalFree(dataDecrypted.pbData); if (descOut) LocalFree(descOut); } else { wcout << L"解密失败,错误码: " << GetLastError() << endl; } // 释放加密数据的内存 LocalFree(dataEncrypted.pbData); return 0; }
关键说明
- 必须配对使用CryptProtectData/CryptUnprotectData:只有前者生成的二进制数据才能被后者解密,不能直接传入普通文本。
- 编码一致性:示例使用Unicode宽字符(
wstring/L""),避免ANSI/Unicode转换问题,和官方实现逻辑保持一致。 - 内存管理:函数返回的
DATA_BLOB中的pbData需要用LocalFree释放,避免内存泄漏。 - 长度计算:对于字符串,直接用
size() * sizeof(wchar_t)计算字节数,不要用strlen(加密数据可能包含空字符)。
内容的提问来源于stack exchange,提问作者user21082594
相关产品推荐
相关产品推荐

