Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RandomNumberGenerator vs RNGCryptoServiceProvider

According to MSDN documentation for RandomNumberGenerator:

Application code does not directly use this class. This abstract class is provided as the base class for all cryptographic random number generators.

For an implementation of a cryptographic random number generator, use the derived class RNGCryptoServiceProvider.

However, I have seen the following code used on a few occassions in different code bases:

byte[] bytes = new byte[...];
RandomNumberGenerator rng = RandomNumberGenerator.Create();
rng.GetBytes(bytes);

Most notably with StackExchange (which I assume includes SO) and also with BCrypt.Net.

Therefore, I am a little confused - what type of RandomNumberGenerator is the above code returning? Also is it a bit of a flaw that some code bases are using RandomNumberGenerator rather than RNGCryptoServiceProvider?

I assume RandomNumberGenerator.Create() is doing under the hood which I am completely missing here, but technically (as it's an abstract class) shouldn't the above code throw an error?

like image 593
James Avatar asked Sep 08 '12 09:09

James


People also ask

Is RNGCryptoServiceProvider obsolete?

RNGCryptoServiceProvider is marked as obsolete, starting in . NET 6. Using it in code generates warning SYSLIB0023 at compile time.

What is RNGCryptoServiceProvider?

RNGCryptoServiceProvider is obsolete. To generate a random number, use one of the RandomNumberGenerator static methods instead. Implements a cryptographic Random Number Generator (RNG) using the implementation provided by the cryptographic service provider (CSP). This class cannot be inherited.

Is RNGCryptoServiceProvider secure?

The RNGCryptoServiceProvider is the default implementation of a security standards compliant random number generator. If you need a random variable for security purposes, you must use this class, or an equivalent, but don't use System. Random because it is highly predictable.


1 Answers

The RandomNumberGenerator.Create() method calls RandomNumberGenerator.Create("System.Security.Cryptography.RandomNumberGenerator"), which will eventually create an instance of RNGCryptoServiceProvider.

(It does some lookups in a pair of dictionaries, so it's likely that you can change the behaviour of that call by registering a default random generator somewhere.)

The actual type of the object returned is not known at compile time, it's only known that it will inherit the RandomNumberGenerator class, so you can use a RandomNumberGenerator reference variable for it.

This way of creating different types of instances depending on the input is used in a couple of places in the framework, for example by the WebRequest.Create method.


Someone at Micrsoft has "fixed" the current documentation (framework 4.5) for the Create() method. It now says:

"When overridden in a derived class, creates an instance of the default implementation of a cryptographic random number generator that can be used to generate random data."

The documentation for framework 4.0 says:

"Creates an instance of the default implementation of a cryptographic random number generator that can be used to generate random data."

This is the correct description of what the method does. I will put in a request to put that description back in the newer documentation.

like image 188
Guffa Avatar answered Oct 02 '22 23:10

Guffa