I am trying to generate cryptographically secure numbers in Windows. I have the following code:
#ifndef w64crypt
#define w64crypt
#include <windows.h>
#include <bcrypt.h>
unsigned long getSeed(ULONG buffer_size){
NTSTATUS status=0;
ULONG flags=0;
PUCHAR c_seed;
BCRYPT_ALG_HANDLE handle;
status=BCryptOpenAlgorithmProvider(
&handle,BCRYPT_RNG_ALGORITHM,NULL,0
);
if(!BCRYPT_SUCCESS(status)){
cout << "BCryptOpenAlgorithmProvider";
printf("%X",status);
}
status=BCryptGenRandom(
handle,c_seed,128,0
);
if(!BCRYPT_SUCCESS(status)){
cout << "Error in BCryptGenRandom";
printf("%X",status);
}
status=BCryptCloseAlgorithmProvider(
handle,0
);
if(!BCRYPT_SUCCESS(status)){
cout << "BCryptCloseAlgorithmProvider";
printf("%X",status);
}
unsigned long seedNo=(unsigned long)c_seed;
return seedNo;
}
#endif
When I run this, I get Error in BCryptGenRandom C0000008
, which is STATUS_INVALID_HANDLE
. This is what the documentation calls for:
https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptopenalgorithmprovider
NTSTATUS BCryptOpenAlgorithmProvider(
BCRYPT_ALG_HANDLE *phAlgorithm,
LPCWSTR pszAlgId,
LPCWSTR pszImplementation,
ULONG dwFlags
);
https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
NTSTATUS BCryptGenRandom(
BCRYPT_ALG_HANDLE hAlgorithm,
PUCHAR pbBuffer,
ULONG cbBuffer,
ULONG dwFlags
);
The above link also states that pszAlgId
must be:
The handle of an algorithm provider created by using the BCryptOpenAlgorithmProvider function. The algorithm that was specified when the provider was created must support the random number generator interface.
Looking at https://learn.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-identifiers, BCRYPT_RNG_ALGORITHM
is my ideal candidate.
I'm compiling this using mingw-w64
, cross-compiling from Ubuntu 18.04.
Why am I receiving this NTSTATUS
?
I know that I'm late, but hopefully this helps people who're having the same issue.
The documentation doesn't mention it, but you can use one of the predefined pseudo-handles for common algorithms. Here's an example
unsigned int GenAESKey(char* keyb) {
NTSTATUS s;
/*BCRYPT_ALG_HANDLE algh;
s = BCryptOpenAlgorithmProvider(&algh, BCRYPT_RNG_ALGORITHM, MS_PLATFORM_CRYPTO_PROVIDER, 0);
if (s != STATUS_SUCCESS)
return (unsigned int)s;*/
s = BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, (PUCHAR)keyb, CABINET_AES_KEY_S, 0);
if (s != STATUS_SUCCESS)
return (unsigned int)s;
return 0;
You can see the list of all the predefined pseudo-handles here