随机数生成器安全性:BCryptGenRandom与RNGCryptoServiceProvider

时间:2013-10-05 18:52:02

标签: c# .net security random cryptography

对于那些赶时间的人来说, 与NIST SP800-90A内部有争议的Dual_EC_DRBG有关。

关于两个RNG:

  1. 基于Microsoft BCRYPT层的一个是基于他们的C API。 BCryptGenRandom遵循NIST SP800-90A的CTR_DRBG(即使用经过批准的分组密码AES来创建随机位)。然而,目前还不清楚它是否使用硬件随机源作为种子(或种子的一部分)......

  2. Microsoft .NET RNGCryptoServiceProvider基于C#。查看.NET source code(或here),我发现它最终调用了C ++方法CapiNative.GenerateRandomBytes()。应该有一个用于C#=> C ++转换的P / Invoke存根,但我在框架源中的任何地方都找不到它。所以我不知道它是如何实现的。

  3. 有没有人有关于这两个随机数生成器的其他信息?要么/两者都使用HW随机种子(通过较旧的intels中的二极管噪声或最新的intels中有争议的RDRAND)。

    PS:不确定这应该是在Security,StackOverflow还是Cryptography ......

2 个答案:

答案 0 :(得分:4)

  

Microsoft .NET RNGCryptoServiceProvider是基于C#的

不完全是,托管框架类只是Windows内置的Crypto api的一个瘦包装器。名称以ServiceProvider结尾的所有System.Security.Cryptography类都是本机API的包装器。名称以Managed结尾的用户在纯托管代码中实现。因此,XxxServiceProvider类使用FIPS验证的cryptogaphy,XxxManaged类不使用。{/ p>

它并不完全是pinvoke,它使用一种通用机制在CLR代码中进行直接调用。抖动查询具有C ++函数地址的表,并直接编译CALL机器代码指令。该机制在this answer中描述。看看实际的代码是不可能的,它不包含在SSCLI20发行版中,并且被改为使用.NET 4中的QCall机制。

因此断言是不可证实的,但很可能RNGCryptoServiceProvider和传递给BCryptGenRandom()的算法提供程序使用相同的随机数源。在Windows中,advapi.dll中的一个未命名的导出函数,this answer给出了它使用的一个很好的摘要。

如果这真的让您感到担忧,并且您想要一个可靠的信息来源,那么请不要从免费的Q + A网站获取建议,以满足您的安全需求。致电Microsoft支持。

答案 1 :(得分:1)

RFC 4086中提到了Microsoft RNGCryptoServiceProvider

  

7.1.3。 Windows CryptGenRandom

     

Microsoft向广泛部署的Windows用户推荐   操作系统一般是使用CryptGenRandom伪随机   使用CryptAPI加密服务进行号码生成调用   供应商。这需要一个加密服务提供者的句柄   library,指向缓冲区的指针,调用者可以通过该缓冲区提供熵   并且返回所生成的伪随机性,以及   指示需要多少个八位字节的随机性。

     

Windows CryptAPI加密服务提供程序存储种子   每个用户的状态变量。当调用CryptGenRandom时,就是这样   结合通话中提供的任何随机性和各种   系统和用户数据,如进程ID,线程ID,系统时钟,   系统时间,系统计数器,内存状态,可用磁盘集群和   散列用户环境块。这些数据都被送到SHA-1和   输出用于为RC4密钥流设定种子。该密钥流用于   产生请求的伪随机数据并更新用户的种子   状态变量。

     

Windows“.NET”的用户可能会发现使用它更容易   RNGCryptoServiceProvider.GetBytes方法接口。