C# program to generate secure random numbers

For secure random numbers, use the RNGCryptoServiceProvider class or the newer RandomNumberGenerator class. These implement cryptographic random number generators that are suitable for security-sensitive applications like generating passwords, tokens, or encryption keys.

Secure random numbers differ from regular Random class numbers because they use entropy from the operating system and are cryptographically secure, making them unpredictable even if an attacker knows some previously generated values.

Syntax

Following is the syntax for generating secure random bytes −

using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider()) {
   byte[] randomBytes = new byte[4];
   crypto.GetBytes(randomBytes);
   int randomValue = BitConverter.ToInt32(randomBytes, 0);
}

For .NET Core and .NET 5+, use the static method −

byte[] randomBytes = new byte[4];
RandomNumberGenerator.Fill(randomBytes);
int randomValue = BitConverter.ToInt32(randomBytes);

Using RNGCryptoServiceProvider

Example

using System;
using System.Security.Cryptography;

public class SecureRandomDemo {
   public static void Main(string[] args) {
      Console.WriteLine("Secure Random Integers:");
      for (int i = 0; i < 5; i++) {
         Console.WriteLine(GenerateSecureRandomInt());
      }
      
      Console.WriteLine("\nSecure Random Doubles (0.0 to 1.0):");
      for (int i = 0; i < 5; i++) {
         Console.WriteLine(GenerateSecureRandomDouble().ToString("F5"));
      }
   }
   
   private static int GenerateSecureRandomInt() {
      using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider()) {
         byte[] randomBytes = new byte[4];
         crypto.GetBytes(randomBytes);
         return Math.Abs(BitConverter.ToInt32(randomBytes, 0));
      }
   }
   
   private static double GenerateSecureRandomDouble() {
      using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider()) {
         byte[] randomBytes = new byte[4];
         crypto.GetBytes(randomBytes);
         uint randomUint = BitConverter.ToUInt32(randomBytes, 0);
         return randomUint / (double)uint.MaxValue;
      }
   }
}

The output of the above code is −

Secure Random Integers:
1847263054
892635471
1564738293
573829164
2039485726

Secure Random Doubles (0.0 to 1.0):
0.43582
0.67291
0.18574
0.82963
0.35427

Using RandomNumberGenerator (Modern Approach)

Example

using System;
using System.Security.Cryptography;

public class ModernSecureRandom {
   public static void Main(string[] args) {
      Console.WriteLine("Secure Random Numbers using RandomNumberGenerator:");
      
      for (int i = 0; i < 5; i++) {
         Console.WriteLine("Random Int: " + GenerateSecureInt());
      }
      
      Console.WriteLine("\nSecure Random Range (1-100):");
      for (int i = 0; i < 5; i++) {
         Console.WriteLine(GenerateSecureRange(1, 100));
      }
   }
   
   private static int GenerateSecureInt() {
      byte[] randomBytes = new byte[4];
      using (RandomNumberGenerator rng = RandomNumberGenerator.Create()) {
         rng.GetBytes(randomBytes);
      }
      return Math.Abs(BitConverter.ToInt32(randomBytes, 0));
   }
   
   private static int GenerateSecureRange(int min, int max) {
      if (min >= max) throw new ArgumentException("min must be less than max");
      
      byte[] randomBytes = new byte[4];
      using (RandomNumberGenerator rng = RandomNumberGenerator.Create()) {
         rng.GetBytes(randomBytes);
      }
      
      uint randomUint = BitConverter.ToUInt32(randomBytes, 0);
      int range = max - min;
      return min + (int)(randomUint % (uint)range);
   }
}

The output of the above code is −

Secure Random Numbers using RandomNumberGenerator:
Random Int: 1234567890
Random Int: 987654321
Random Int: 1122334455
Random Int: 2233445566
Random Int: 3344556677

Secure Random Range (1-100):
42
17
83
29
65

Generating Secure Random Passwords

Example

using System;
using System.Security.Cryptography;
using System.Text;

public class SecurePasswordGenerator {
   private static readonly string Characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
   
   public static void Main(string[] args) {
      Console.WriteLine("Secure Random Passwords:");
      for (int i = 0; i < 5; i++) {
         Console.WriteLine(GenerateSecurePassword(12));
      }
   }
   
   private static string GenerateSecurePassword(int length) {
      StringBuilder password = new StringBuilder();
      using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider()) {
         byte[] randomBytes = new byte[length];
         crypto.GetBytes(randomBytes);
         
         for (int i = 0; i < length; i++) {
            int index = randomBytes[i] % Characters.Length;
            password.Append(Characters[index]);
         }
      }
      return password.ToString();
   }
}

The output of the above code is −

Secure Random Passwords:
K7m@9XzQ4!pL
B3n&8RvE2$wY
P6s#5TuI1%oM
D9j*7CfH0@aG
V4x%2WqZ8!eN

Comparison: Regular vs Secure Random

Regular Random Secure Random
Uses pseudorandom algorithm Uses cryptographically secure algorithm
Predictable if seed is known Unpredictable even with previous values
Fast generation Slower due to entropy gathering
Suitable for games, simulations Suitable for passwords, tokens, keys

Conclusion

Use RNGCryptoServiceProvider or RandomNumberGenerator for generating secure random numbers in security-sensitive applications. These classes provide cryptographically secure randomness that is unpredictable and suitable for generating passwords, encryption keys, and authentication tokens.

Updated on: 2026-03-17T07:04:35+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements