In this article, we’ll explore how to generate random cryptographic numbers with RandomNumberGenerator API in C#, and why it is paramount in the context of cryptography.Â

Let’s begin!

## Overview of Cryptography

Cryptography is the practice of securing information and communications so that only authorized parties can access it. It uses encryption, decryption, and hashing techniques to protect the confidentiality and integrity of messages passing over the communications channel.Â The `System.Security.Cryptography`

namespace within the .NET BCL provides robust support for cryptography APIs.

Next, grasping the significance of generating random numbers in cryptographic algorithms is crucial, so let’s explore that.

## Importance of Random Numbers in Cryptography

Most cryptographic algorithms need a source of random data to generate new keys. Since most computers do not have a hardware-based random number generator, the program will use software-based techniques to generate random numbers as best.

**These random numbers are rarely truly random because software generates them. They are typically pseudorandom, meaning they appear random but are not. The System.Random API also has this problem**.

Next, let’s look at the problems with the `System.Random`

API.

## Problems With the System.Random API

In .NET, we generally use the `System.Random`

API when we need to generate a pseudorandom number.

This number generator provides the seed value when the object is in construction. This is fine for most application scenarios like games and will appear random.

However, this API is insufficient when implementing tight security because it is deterministic and predictable. The current implementation ofÂ `System.Random`

is based on a subtractive random number generator algorithm, which calculates a sequence of random numbers.

Still, each number is congruent to subtracting the previous two numbers from the sequence. So, **we know this API is useless for creating cryptographic secure random numbers.**

Now, let’s delve into security implications in the context of cryptography.

**RandomNumberGenerator vs. System.Random for Cryptography**

The RandomNumberGenerator class is used for number generators specifically designed for cryptographic purposes. **Its platform-specific algorithm implementations produce unpredictable numbers with high entropy (the measure of randomness, the more the better), making it suitable for key generation and cryptographic operations.**

This high entropy is achieved by not relying on the seed value but using system-level entropy sources like system time, mouse movements, or other unpredictable events. In contrast, the `System.Random`

is a general-purpose number generator unsuitable for cryptographic operations due to its lower entropy and deterministic algorithm. Therefore, we can classify these number generators into **CryptoSecureRandom** and **GeneralPurposeRandom**.

## Generate Secure Random Numbers With RandomNumberGenerator API

Let’s take a look at how we can use the `RandomNumberGenerator`

class:

`public static byte[] GenerateSecureRandomKey(int bytesCount) => RandomNumberGenerator.GetBytes(bytesCount);`

Here, we create a `GenerateSecureRandomKey()`

method that calls the `RandomNumberGenerator.GetBytes()`

method. This method generates a random byte array of the specified length. Then, we can convert this byte array into a Base64 string.Â

Let’s see another example of generating a random integer value based on the range provided:

`public static int GenerateSecureRandomInteger(int minValue, int maxValue) => RandomNumberGenerator.GetInt32(minValue, maxValue);`

By using the `GetInt32()`

method, we generate a random integer value that falls in the predefined range.

## Performance Comparison of System.Random and RandomNumberGenerator

To verify that `RandomNumberGenerator`

is slower than `System.Random`

, let’s set up benchmark tests to measure the speed of generating random integers:

[Orderer(SummaryOrderPolicy.FastestToSlowest)] public class RandomNumberBenchmarks { [Benchmark] public int UsingCryptoSecureRandomNumberGenerator() => CryptographicHelpers.GenerateSecureRandomInteger(1, 100); [Benchmark] public int UsingGeneralRandomNumberGenerator() => CryptographicHelpers.GenerateGeneralRandomInteger(1, 100); }

We are testing the `GetInt32()`

method in the `RandomNumberGenerator`

class and the `Next()`

method in `System.Random`

class. *Benchmark tests were conducted by using the *`System.Random.Shared`

* instance.*

Now, let’s compare the speed performance of the crypto-secure random number generator (`RandomNumberGenerator`

) with the general-purpose random number generator (`System.Random`

):

| Method | Mean | Error | StdDev | |--------------------------------------- |----------:|---------:|---------:| | UsingGeneralRandomNumberGenerator | 11.88 ns | 0.245 ns | 0.229 ns | | UsingCryptoSecureRandomNumberGenerator | 154.58 ns | 1.916 ns | 1.793 ns |

**The tradeoff in this approach is that RandomNumberGeneratorÂ is much slower to execute than System.Random**. However, you make a minimal tradeoff when you generate numbers to use as encryption keys.

## Conclusion

So, we learned how to create cryptographic numbers with RandomNumberGenerator API in C#. While both RandomNumberGenerator and System.Random have their places in .NET; understanding their differences is crucial. By choosing the right class for the right job, we can ensure security and efficiency in our applications.