CryptGenRandom输出与rand()调用不同
CryptGenRandom output not getting same as rand() call
我尝试使用CryptGenRandom()调用来创建随机数,以避免加密攻击。我试图运行以下代码,打印rand调用和CryptGenRandom()调用。
HCRYPTPROV hProvider = 0;
const DWORD dwLength = 5;
BYTE pbBuffer[dwLength] = {};
if (!::CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT|CRYPT_SILENT))
return 1;
srand((unsigned)time (0));
for(int i=0; i<10; ++i)
cout<<"rand()::"<<i<<":"<<rand()<<endl;
for (DWORD i = 0; i < dwLength; ++i)
{
if (!::CryptGenRandom(hProvider, dwLength, pbBuffer))
{
::CryptReleaseContext(hProvider, 0);
return 1;
}
std::cout << "windows::"<<i<<"::"<<static_cast<unsigned int>(pbBuffer[0])<< std::endl;
}
if (!::CryptReleaseContext(hProvider, 0))
return 1;
但是rand()
调用的输出是
rand()::0:9754
rand()::1:526
rand()::2:29162
rand()::3:10461
rand()::4:31585
rand()::5:15594
rand()::6:12157
rand()::7:19178
rand()::8:5413
rand()::9:16157
and CryptGenRandom()
call is giving
windows::0::167
windows::1::138
windows::2::197
windows::3::101
windows::4::44
谁能帮助我得到相同的输出是给rand()调用使用CryptGenRandom?CryptGenRandom()只给出3位随机数,这不足以为我在代码中使用的睡眠调用设置值。
问题是你在这里使用了pBuffer[0]
。
static_cast<unsigned int>(pbBuffer[0])
如您的代码所示,pBuffer[0]
是单个BYTE
。这就是为什么你不能得到大于255的值。
如果你想要任何可表示的unsigned int
,你会想要这个
const DWORD dwLength = sizeof(unsigned int);
和这个,使用pBuffer
中的所有字节。
*static_cast<unsigned int*>(pbBuffer)
嗯,它只给出3位数字,因为当你这样做时,你只取一个字节并将其转换为unsigned int
: static_cast<unsigned int>(pbBuffer[0])
和BYTE
(即unsigned char
)只能适合0到255之间的值。
你可以稍微改变一下你的方法:
unsigned int MyGoodRand()
{
// We make this a static so we don't have
// to initialize it all the time because
// that is expensive.
static HCRYPTPROV hProvider = 0;
if(hProvider == NULL)
{
if(!::CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT|CRYPT_SILENT))
return 0;
}
unsigned int randval = 0;
if (!::CryptGenRandom(hProvider, sizeof(unsigned int), static_cast<PBYTE>(&randval)))
randval = 0; // Failure!
return randval;
}
此函数将在失败时返回0
,这是一个问题,因为0也是CryptGenRandom
的可能结果,并且还会泄漏HCRYPTPROV
,因为它只在函数内部可用,一旦分配就没有办法释放它。
我们可以将其扩展为返回true
或false
,并通过调用者的引用接受randval
,但这并不能解决HCRYPTPROV
泄漏问题。让我们创建一个class
,其中HCRYPTPROV
作为成员,operator()
将用于生成新数字。
像这样:
class MYPRNG
{
private:
HCRYPTPROV hProvider;
// declare but not define a private copy constructor to
// prevent copy-construction of this object. If you're
// using C++11 you can use the =delete syntax instead.
MYPRNG(const MYPRNG &o) = delete;
// Same with the default assignment operator.
MYPRNG& operator=(const MYPRNG& o)
public:
MYPRNG()
: hProvider(NULL)
{
if(!::CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT|CRYPT_SILENT))
hProvider = NULL; // ensure that it's NULL
}
~MYPRNG()
{
if(hProvider)
CryptReleaseContext(hProvider, 0);
}
bool operator()(unsigned int &randval)
{
if(hProvider == NULL)
return false;
if (!::CryptGenRandom(hProvider,
sizeof(unsigned int),
static_cast<PBYTE>(&randval)))
return false;
return true;
}
};
现在我们没有泄漏,我们可以很容易地生成随机数并可靠地确定操作是否成功或失败。我们可以这样使用它:
MYPRNG prng;
unsigned int rval;
for(int i = 0; i < 10; i++)
{ // try to get 10 random numbers!
if(!prng(rval))
{
// FAILED TO GENERATE A NEW RANDOM NUMBER!
}
else
{
// A new random number is now in rval. Use it
}
}
相关文章:
- 当使用通配符和null指针调用函数时,对输出的说明
- 有没有办法简单地从 GPU 调用多个 cpp 输出文件?
- 使用静态变量的递归调用的不同输出
- cmake add_custom_command + Xcode:多输出 = 多命令调用
- 调用 cout 时如何在结构中输出常量文本?
- 我的 cout 上有一个奇怪的输出,它把答案放在第一位,然后在我调用它的地方放一个奇怪的输出.我该怎么办?
- 函数调用导致没有输出
- 使用 Node.js N-API 调用 C 函数时,不会显示预期的输出
- 如何调用继承的重载运算符<<并在派生类的输出中添加更多文本?
- 我的动态链接队列在同一输出流中调用时不正确地输出三个返回函数
- 当我从头文件和实现文件调用我的函数到我的主文件时,我没有得到任何输出
- 空指针(为缺少的输出数组调用的 create() 在 create,文件 /home/m/OpenCV/modules/
- 为什么在杂注 omp 关键之后多次调用 printf 会产生乱码输出?
- std::cout 如果从自定义分配器 (Visual Studio 2019) 调用,则不会输出
- 将 Linux system() 调用命令的输出重定向到仅可变的
- QThread 不提供来自调用 shellscript 的输出
- 显示 matlab 程序的输出,调用另一个 C++ 程序
- 输出 = 0 尝试计算标头中的函数并在主程序中调用它们时
- 基于对函数的参数调用流输出运算符的能力重载函数
- 使用读取系统调用C++输出文本