CryptGenRandom()是线程安全的吗?

问题描述:

CryptGenRandom()是否具有单一全局程序范围HCRYPTPROV实例的线程安全性?CryptGenRandom()是线程安全的吗?

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

创建每个线程独立HCRYPTPROV并再次摧毁它事项将显著复杂(也冒险在我身边更多的与安全相关的bug),因此这将是真正有用的知道。共享一个全球HCRYPTPROV肯定会容易很多。

那么有谁知道这里大约CryptGenRandom()的线程安全的,尤其是一个HCRYPTPROV实例?

+0

你为什么不只是锁了吗?会比单独的实例更简单。 –

+0

那么,如果你使用一个应用程序生存期线程池,你可以为每个线程创建一个实例,而不需要不断创建/销毁它们?这不适合你吗? –

+0

是的,这个api调用实际上是线程安全的。为什么你认为这里可能会有一些线程干扰? – RbMm

创建每个线程独立HCRYPTPROV并没有太大的意义。这是在当前所有实现中堆栈中指向内存块的指针,主要保存指向CSP entry points的指针,这些指针用于调用实际的提供者实现(在我们的例子中为CPGenRandom)。引用自身不包含状态CSP的,不像例如其中包含实际的国家重点HCRYPTKEY。所以即使你为每个线程创建了一个单独的HCRYPTPROV - 这都不会改变。

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

至于结果,我想CPGenRandom必须设计是线程安全的。而且我用一个众所周知的微软CSP测试这是真的。内部同步用于功能,当需要访问全局数据并且多个线程同时调用CPGenRandom;每个线程都接收唯一的随机数据

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

+0

非常感谢这个详细的分析和非常合理的推理。这让我非常有信心,这个答案确实是正确的。谢谢! –