BCryptGenRandom STATUS_INVALID_HANDLE
BCryptGenRandom STATUS_INVALID_HANDLE
我正在尝试在 Windows 中生成加密安全号码。我有以下代码:
#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
当我运行这个时,我得到Error in BCryptGenRandom C0000008
,也就是STATUS_INVALID_HANDLE
。这是文档要求的内容:
https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptopenalgorithmprovider
NTSTATUS BCryptOpenAlgorithmProvider(
BCRYPT_ALG_HANDLE *phAlgorithm,
LPCWSTR pszAlgId,
LPCWSTR pszImplementation,
ULONG dwFlags
);
https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
NTSTATUS BCryptGenRandom(
BCRYPT_ALG_HANDLE hAlgorithm,
PUCHAR pbBuffer,
ULONG cbBuffer,
ULONG dwFlags
);
上面的link也说明了pszAlgId
必须是:
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.
看着https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-identifiers,BCRYPT_RNG_ALGORITHM
是我的理想人选。
我正在使用 mingw-w64
进行编译,从 Ubuntu 18.04.
进行交叉编译
为什么我会收到这个 NTSTATUS
?
我知道我来晚了,但希望这对遇到同样问题的人有所帮助。
文档中没有提及,但您可以使用预定义的 pseudo-handles 之一用于常用算法。这是一个例子
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;
可以看到所有预定义的列表pseudo-handleshere
这为我解决了:
unsigned long getSeed(int size){
BCRYPT_ALG_HANDLE handle;
int Buffer;
PUCHAR bPointer=(PUCHAR)&Buffer;
if(!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(
&handle,BCRYPT_RNG_ALGORITHM,NULL,0
))){
std::cout << "BCryptOpenAlgorithmProvider failure\n";
}
NTSTATUS status=BCRYPT_SUCCESS(BCryptGenRandom(
&handle,bPointer,sizeof(Buffer),0
));
if(!BCRYPT_SUCCESS(status)){
printf("%X",status);
std::cout << "Error in BCryptGenRandom";
}
BCryptCloseAlgorithmProvider(
handle,0
);
return static_cast<int>(reinterpret_cast<intptr_t>(bPointer));
}
原始代码在调用 BCryptGenRandom
时声称缓冲区为 128 字节,但事实并非如此。原始代码中名为 c_seed
的缓冲区是一个野指针,最有可能的大小为 8。
在这种情况下,c_seed
,现在别名为 bPointer
,不再是狂野的 - 它指向 int Buffer
。此缓冲区的大小正在使用 sizeof
宏传递给函数,因此尽管它的大小可能为 8,但它可以适应我使用的 cross-compiler 需要的任何目标架构。
我正在尝试在 Windows 中生成加密安全号码。我有以下代码:
#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
当我运行这个时,我得到Error in BCryptGenRandom C0000008
,也就是STATUS_INVALID_HANDLE
。这是文档要求的内容:
https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptopenalgorithmprovider
NTSTATUS BCryptOpenAlgorithmProvider(
BCRYPT_ALG_HANDLE *phAlgorithm,
LPCWSTR pszAlgId,
LPCWSTR pszImplementation,
ULONG dwFlags
);
https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
NTSTATUS BCryptGenRandom(
BCRYPT_ALG_HANDLE hAlgorithm,
PUCHAR pbBuffer,
ULONG cbBuffer,
ULONG dwFlags
);
上面的link也说明了pszAlgId
必须是:
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.
看着https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-identifiers,BCRYPT_RNG_ALGORITHM
是我的理想人选。
我正在使用 mingw-w64
进行编译,从 Ubuntu 18.04.
为什么我会收到这个 NTSTATUS
?
我知道我来晚了,但希望这对遇到同样问题的人有所帮助。
文档中没有提及,但您可以使用预定义的 pseudo-handles 之一用于常用算法。这是一个例子
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;
可以看到所有预定义的列表pseudo-handleshere
这为我解决了:
unsigned long getSeed(int size){
BCRYPT_ALG_HANDLE handle;
int Buffer;
PUCHAR bPointer=(PUCHAR)&Buffer;
if(!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(
&handle,BCRYPT_RNG_ALGORITHM,NULL,0
))){
std::cout << "BCryptOpenAlgorithmProvider failure\n";
}
NTSTATUS status=BCRYPT_SUCCESS(BCryptGenRandom(
&handle,bPointer,sizeof(Buffer),0
));
if(!BCRYPT_SUCCESS(status)){
printf("%X",status);
std::cout << "Error in BCryptGenRandom";
}
BCryptCloseAlgorithmProvider(
handle,0
);
return static_cast<int>(reinterpret_cast<intptr_t>(bPointer));
}
原始代码在调用 BCryptGenRandom
时声称缓冲区为 128 字节,但事实并非如此。原始代码中名为 c_seed
的缓冲区是一个野指针,最有可能的大小为 8。
在这种情况下,c_seed
,现在别名为 bPointer
,不再是狂野的 - 它指向 int Buffer
。此缓冲区的大小正在使用 sizeof
宏传递给函数,因此尽管它的大小可能为 8,但它可以适应我使用的 cross-compiler 需要的任何目标架构。