CryptGenRandom() 是线程安全的吗?

Is CryptGenRandom() thread-safe?

对于单个全局程序范围的 HCRYPTPROV 实例,CryptGenRandom() 是线程安全的吗?

MSDN 似乎缺少这方面的任何信息:https://msdn.microsoft.com/en-us/library/windows/desktop/aa379942(v=vs.85).aspx

为每个线程创建一个单独的 HCRYPTPROV 并再次销毁它会使事情变得非常复杂(而且我这边还会冒更多与安全相关的错误的风险),所以这将非常有用。共享一个全局 HCRYPTPROV 肯定会容易得多。

这里有人知道 CryptGenRandom() 的线程安全性吗,尤其是单个 HCRYPTPROV 实例?

为每个线程创建一个单独的 HCRYPTPROV 没有多大意义。这是所有当前实现中指向堆内存块的指针,主要保存指向 CSP entry points 的指针,用于调用实际提供程序实现(在我们的例子中是 CPGenRandom)。引用本身不包含 CSPstate,不像 HCRYPTKEY 那样包含实际的键状态。因此,即使您为每个线程创建一个单独的 HCRYPTPROV - 这也没有任何改变。

在此调用期间,CSP 内部可能使用了一些全局变量/数据;然而,这是未知的,因为这些将是实施细节。当然我们可以在代码中序列化对CryptGenRandom的调用。但是,我们无法控制进程中的其他一些 dll 也同时调用 CryptGenRandom。所以序列化所有对 CryptGenRandom 的调用也是不可能的。

因此我认为 CPGenRandom 必须设计为线程安全的。我用一个著名的 Microsoft CSP 进行的测试是正确的。内部同步用在函数中,当需要访问全局数据时,如果多个线程并发调用CPGenRandom;每个线程都会收到唯一的随机数据。

所以我的结论 - CryptGenRandom 是线程安全的,至少对于所有 Microsoft CSP