c++ 为什么BCryptDeriveKeyPBKDF2返回状态无效参数?

ngynwnxp  于 2022-12-15  发布在  其他
关注(0)|答案(1)|浏览(203)
#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;
    BCRYPT_HASH_HANDLE phHash = nullptr;
    LPCWSTR pszAlgId = TEXT("XTS-AES");
    LPCWSTR pszImplementation  = TEXT("Advanced Encryption Standard");
    PUCHAR pbHashObject = 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 }; // 771f5b302cf7c531a9864652e2ff4a17abd002dd4fb02f710fe5a81afee79c6b

    

    NTSTATUS status = BCryptOpenAlgorithmProvider(
        &phAlgorithm,
        BCRYPT_PBKDF2_ALGORITHM,
        NULL,
        NULL
    ); 
    test_status(status);

  
 
    PUCHAR pbOutput = nullptr;
    ULONG pcbResult = NULL;

    status = BCryptGetProperty(
        phAlgorithm,
        BCRYPT_OBJECT_LENGTH,
        pbOutput,
        sizeof(DWORD),
        &pcbResult,
        NULL
    );
    test_status(status);
    PUCHAR DerivedKey = nullptr;
    DWORD cbDerivedKey = NULL;

    std::string pbPassword = "MySecretPass";
    std::string DerivedKeyString;
    status = BCryptDeriveKeyPBKDF2(
        phAlgorithm,
        (BYTE*)pbPassword.data(),
        pbPassword.length(),
        (BYTE*)pbSalt.data(),
        sizeof(BYTE),
        10000,
        (PUCHAR)DerivedKeyString.c_str(),
        64,
        0);
      test_status(status);
   
   
    status = BCryptCloseAlgorithmProvider(
        phAlgorithm,
        NULL
    );

    test_status(status);
}

这段代码应该从密码中获取密钥,但是在生成这个密钥的这个阶段,我得到了一个错误STATUS_INVALID_PARAMETER。

  • 我试图改变加密算法,并以不同的方式传递参数,但所有这一切都没有导致成功或给出错误STATUS_INVALID_PARAMETER。
gojuced7

gojuced71#

有两个错误:
首先,您正在执行散列计算,BCryptOpenAlgorithmProvider函数必须使用标志和标识符作为散列函数的行为。在BCryptOpenAlgorithmProvider函数中,将BCRYPT_PBKDF2_ALGORITHM替换为BCRYPT_SHA256_ALGORITHM,在第四个dwFlags参数中使用BCRYPT_ALG_HANDLE_HMAC_FLAG
这两个参数的文档如下所示:
https://learn.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-identifiershttps://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptopenalgorithmprovider
其次,参数pbDerivedKey不要使用字符串类型,否则会导致内存崩溃,将std::string DerivedKeyString替换为BYTE DerivedKeyString[64],在函数BCryptDeriveKeyPBKDF2中,将(PUCHAR)DerivedKeyString.c_str()替换为DerivedKeyString

相关问题