Yesterday's post about Random
class got some traction, and I did not highlight one crucial aspect of it. Random
is not security-safe class and shouldn't be used for any security related code. Values generated by random are really pseudo-random values. They are generated by an algorithm and are based on seed value. Knowing the seed, we can generate the same values. Constructing without providing seed will use the following seed, depending on the framework:
- 📌In .NET Framework, the default seed value is time-dependent.
- 📌In .NET Core, the default seed value is produced by the thread-static, pseudo-random number generator.
For security-related purposes, use RandomNumberGenerator
from System.Security.Cryptography
namespace.
Docs:
- 📑 https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator?view=net-8.0 (1)
- 📑 https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-random (2)
Documentation (2) states that the algorithm used for generating numbers is based on "Knuth's subtractive random number generator algorithm" but that seems to be only part of the truth.
Checking the code (see: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Random.cs#L33) it looks like for seedless direct usage of Random the algorithm is Xoshiro (see: https://en.wikipedia.org/wiki/Xorshift#xoshiro) in other cases the Net5CompatDerivedImpl is used. That one is based on Knuth's algorithm.
// ✅ For security releated needs use RnadomNumberGenerator class
byte[] randomBytes = RandomNumberGenerator.GetBytes(16);