Random number generator security: BCryptGenRandom

2019-07-16 05:19发布

For those in a hurry, this is NOT related to the controversial Dual_EC_DRBG planted inside NIST's SP800-90A.

About the two RNGs:

  1. The Microsoft BCRYPT layer based one is over their C API. BCryptGenRandom is following NIST SP800-90A's CTR_DRBG (i.e. uses an approved block cipher, AES, to create random bits). However it is unclear if it uses a hardware random source as seed (or part of the seed)...

  2. The Microsoft .NET RNGCryptoServiceProvider is C# based. Looking at the .NET source code (or here), I see it end up calling the C++ method CapiNative.GenerateRandomBytes(). There should have been a P/Invoke stub for the C#=>C++ transition but I couldn't find it anywhere in the framework source. So I have no idea how it's actually implemented.

Does anyone have additional information on these two random number generators? Do either/both use HW random seeds (either via diode noise in older intels or the controversial RDRAND in the latest intels).

PS: Not sure it this should be at Security, StackOverflow or Cryptography ...

2条回答
乱世女痞
2楼-- · 2019-07-16 05:32

Microsoft RNGCryptoServiceProvider is mentioned in RFC 4086:

7.1.3. Windows CryptGenRandom

Microsoft's recommendation to users of the widely deployed Windows operating system is generally to use the CryptGenRandom pseudo-random number generation call with the CryptAPI cryptographic service provider. This takes a handle to a cryptographic service provider library, a pointer to a buffer by which the caller can provide entropy and into which the generated pseudo-randomness is returned, and an indication of how many octets of randomness are desired.

The Windows CryptAPI cryptographic service provider stores a seed state variable with every user. When CryptGenRandom is called, this is combined with any randomness provided in the call and with various system and user data such as the process ID, thread ID, system clock, system time, system counter, memory status, free disk clusters, and hashed user environment block. This data is all fed to SHA-1, and the output is used to seed an RC4 key stream. That key stream is used to produce the pseudo-random data requested and to update the user's seed state variable.

Users of Windows ".NET" will probably find it easier to use the RNGCryptoServiceProvider.GetBytes method interface.

查看更多
再贱就再见
3楼-- · 2019-07-16 05:48

The Microsoft .NET RNGCryptoServiceProvider is a C# based

Not exactly, the managed framework class is just a thin wrapper over the Crypto api built into Windows. All the System.Security.Cryptography classes whose name end with ServiceProvider are wrappers for the native API. Those whose name ends in Managed are implemented in pure managed code. Accordingly, the XxxServiceProvider classes use FIPS validated cryptogaphy, and the XxxManaged classes are not.

It is not exactly pinvoke, it uses a common mechanism to make direct calls in CLR code. The jitter consults a table with addresses of C++ functions and compiles the CALL machine code instruction directly. The mechanism is described in this answer. Having a look at the actual code isn't possible, it isn't included in the SSCLI20 distribution and was altered to use the QCall mechanism in .NET 4.

So the assertion is unprovable, but it is pretty likely that RNGCryptoServiceProvider and the algorithm provider you pass to BCryptGenRandom() use the same source for random numbers. Which in Windows is an unnamed exported function in advapi.dll, this answer gives an excellent summary of what it uses.

If this truly concerns you and you want a reliable source of information then don't take advice from a free Q+A web site for your security needs. Call Microsoft Support.

查看更多
登录 后发表回答