BCryptDeriveKeyPBKDF2返回STATUS_INVALID_PARAMETER的原因与修复
BCryptDeriveKeyPBKDF2返回STATUS_INVALID_PARAMETER的原因与修复方案
错误原因分析
原代码触发STATUS_INVALID_PARAMETER的核心问题有三个:
- Salt长度参数错误:调用
BCryptDeriveKeyPBKDF2时,传入的salt长度是sizeof(BYTE)(即1字节),但实际salt是32字节的vector,长度参数不匹配直接导致参数校验失败。 - 输出缓冲区无效:使用
std::string::c_str()作为输出缓冲区,该函数返回只读的const指针,不允许写入操作;同时原字符串未分配64字节的存储空间,缓冲区既不可写也大小不足。 - 多余的无效API调用:调用
BCryptGetProperty获取BCRYPT_OBJECT_LENGTH时,传入的pbOutput是nullptr,会触发STATUS_INVALID_PARAMETER,虽不直接影响后续PBKDF2调用,但属于无效冗余操作。
修复方案
针对上述问题逐一修正:
- 修正Salt长度参数:将salt长度改为
pbSalt.size(),传递实际的32字节长度。 - 替换输出缓冲区:使用
std::vector<BYTE>作为输出缓冲区,预先分配64字节空间,保证可写且大小足够。 - 移除无效API调用:删除多余的
BCryptGetProperty调用,PBKDF2算法不需要获取对象长度属性。 - 清理冗余变量:移除代码中未使用的
phHash、pszAlgId等变量,精简代码结构。
修正后的完整代码
#include <iostream> #include <Windows.h> #include <bcrypt.h> #include <ntstatus.h> #include <string> #include <vector> #pragma comment(lib, "bcrypt.lib") void test_status(NTSTATUS return_val) { switch (return_val) { case STATUS_SUCCESS: std::cout << "STATUS_SUCCESS\n"; break; case STATUS_BUFFER_TOO_SMALL: std::cout << "STATUS_BUFFER_TOO_SMALL\n"; break; case STATUS_INVALID_HANDLE: std::cout << "STATUS_INVALID_HANDLE\n"; break; case STATUS_INVALID_PARAMETER: std::cout << "STATUS_INVALID_PARAMETER\n"; break; case STATUS_NOT_SUPPORTED: std::cout << "STATUS_NOT_SUPPORTED\n"; break; } } int main() { BCRYPT_ALG_HANDLE phAlgorithm = nullptr; std::vector<BYTE> pbSalt = { 0x77, 0x1f, 0x5b, 0x30, 0x2c, 0xf7, 0xc5, 0x31, 0xa9, 0x86, 0x46, 0x52, 0xe2, 0xff, 0x4a, 0x17, 0xab, 0xd0, 0x02, 0xdd, 0x4f, 0xb0, 0x2f, 0x71, 0x0f, 0xe5, 0xa8, 0x1a, 0xfe, 0xe7, 0x9c, 0x6b }; // 打开PBKDF2算法提供者 NTSTATUS status = BCryptOpenAlgorithmProvider( &phAlgorithm, BCRYPT_PBKDF2_ALGORITHM, NULL, NULL ); test_status(status); if (status == STATUS_SUCCESS) { std::string pbPassword = "MySecretPass"; // 预先分配64字节的输出缓冲区 std::vector<BYTE> DerivedKey(64); // 调用PBKDF2生成密钥 status = BCryptDeriveKeyPBKDF2( phAlgorithm, reinterpret_cast<BYTE*>(pbPassword.data()), static_cast<ULONG>(pbPassword.length()), pbSalt.data(), static_cast<ULONG>(pbSalt.size()), 10000, DerivedKey.data(), static_cast<ULONG>(DerivedKey.size()), 0 ); test_status(status); // 关闭算法提供者 status = BCryptCloseAlgorithmProvider(phAlgorithm, NULL); test_status(status); } return 0; }
内容的提问来源于stack exchange,提问作者Arthur Akopiants
相关产品推荐
相关产品推荐

