【问题标题】:CryptGenRandom is giving same value while calling in loopCryptGenRandom 在循环调用时给出相同的值
【发布时间】:2013-06-04 06:26:57
【问题描述】:

抱歉,我不能为此使用单独的类,我尝试构建以下代码并在循环中从外部调用时获得相同的输出。

unsigned int crypt_rand()
{
    HCRYPTPROV hProvider = 0;
    const DWORD dwLength = sizeof(unsigned int);
    unsigned int pbBuffer[dwLength] = {};

    if (!::CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
        return 1;
    if (!::CryptGenRandom(hProvider, sizeof(unsigned int), reinterpret_cast<PBYTE>(&pbBuffer)))
    {
        ::CryptReleaseContext(hProvider, 0);
        return 1;
    }
    if (!::CryptReleaseContext(hProvider, 0))
        return 1;
    return (unsigned int)pbBuffer;

}                                      

如果我每次都从循环中调用这个函数,得到相同的输出。在这个方法中,我可以像输入一样给出什么吗?你能帮我吗?

for (DWORD i = 0; i < 5; ++i)
    {
        rand_no = crypt_rand();
        std::cout << "windows::"<<i<<"::"<<rand_no<< std::endl;
    }

输出是

windows::0::4519964
windows::1::4519964
windows::2::4519964
windows::3::4519964
windows::4::4519964

【问题讨论】:

  • 我建议你仔细看看你从crypt_rand返回的内容...
  • 我正在返回整个缓冲区。我的要求是在每次调用中获得不同的随机值。

标签: c++ c windows visual-c++


【解决方案1】:

使用转换(reinterpret_castreturn 语句中的转换)隐藏了一些重要的编译器错误,这些错误可以让您一开始就正确编写此代码。

尽可能避免强制转换,改为修复类型。

CryptGenRandom 需要一个

BYTE *pbBuffer

参数。传递一个指向BYTE 数组的指针不是别的(你传递的是一个指向int 数组的指针)。

在您的退货声明中,您将地址转换为unsigned int。您需要获取 BYTE 数组并将其包含的 values 转换为 int(您可以在网上找到该示例,或者您可以通过轮班和添加自己制作一个)。您现在所做的可能是一遍又一遍地输出相同的地址(或其中的一部分)。

为了澄清,将您的数组定义为

BYTE pbBuffer[dwLength] = {};

并将您的函数称为

::CryptGenRandom(hProvider, dwLength, pbBuffer)

避免强制转换,尤其是 C 风格的强制转换,并阅读有关数组的信息。在 C++ 中,当传递给函数时,数组衰减为指向数组第一个元素的指针。如果您有一个 BYTE 数组,它将衰减为 BYTE*,您的函数的预期类型。

【讨论】:

  • 我无法在支持 BYTE 的方法中使用 BYTE *pbBuffer。您能提供任何我可以分析和尝试的示例代码吗?
  • 如果我使用 BYTE*,我无法在 CryptGenRandom() 中作为参数传递。那你能帮我怎么做吗?
【解决方案2】:

问题出在return (unsigned int)pbBuffer; 这里你每次都只是获取 pbBUffer 的地址。如果 pbBuffer 是一个数组并且函数 crypt_rand 返回 unsigned int 那么它应该是返回时数组的元素。

您需要在编译期间启用警告。这些可能的错误必须作为警告出现。

【讨论】:

  • 我需要为每个 crypt_rand() 调用获取一个随机数。你能帮我这样做吗?或者你能建议我怎么做吗?
【解决方案3】:

您想要一个无符号整数的随机数吗? 只需将 BYTE 缓冲区的内容转换为无符号整数

怎么样:

unsigned int crypt_rand()
{
    HCRYPTPROV hProvider = 0;
    const DWORD dwLength = sizeof(unsigned int);
    BYTE buffer[dwLength];

    if (!::CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
        return 1;
    if (!::CryptGenRandom(hProvider, sizeof(buffer), &buffer))
    {
        ::CryptReleaseContext(hProvider, 0);
        return 1;
    }
    if (!::CryptReleaseContext(hProvider, 0))
        return 1;
    return *(unsigned int*)buffer;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    相关资源
    最近更新 更多