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?
RNGCryptoServiceProvider is marked as obsolete, starting in . NET 6. Using it in code generates warning SYSLIB0023 at compile time.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With