Home > OS >  Why BCryptDeriveKeyPBKDF2 return STATUS_INVALID_PARAMETER?
Why BCryptDeriveKeyPBKDF2 return STATUS_INVALID_PARAMETER?

Time:12-10



#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);
}

This code should get the key from the password, but at this stage of generating this key, I get an error STATUS_INVALID_PARAMETER. Why is this happening and how to fix it

-I tried to change the encryption algorithm and pass the parameters in a different way, but all this did not lead to success or gave the error STATUS_INVALID_PARAMETER.

CodePudding user response:

There are two errors:

Firstly, you are performing hash computation, the BCryptOpenAlgorithmProvider function must use flags and identifiers for the hash function's behavior. In the function BCryptOpenAlgorithmProvider, replace BCRYPT_PBKDF2_ALGORITHM with BCRYPT_SHA256_ALGORITHM, use BCRYPT_ALG_HANDLE_HMAC_FLAG in the fourth dwFlags parameter.

The documentation for these two parameters is as follows:

https://learn.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-identifiers https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptopenalgorithmprovider

Secondly, do not use string type of the parameter pbDerivedKey, or it will crash the memory. Replace std::string DerivedKeyString with BYTE DerivedKeyString[64]. In the function BCryptDeriveKeyPBKDF2, replace (PUCHAR)DerivedKeyString.c_str() with DerivedKeyString.

  • Related