C# Password Generator

Generate cryptographically secure passwords in C# using System.Security.Cryptography.RandomNumberGenerator.

The Secure Way

Since .NET 6, RandomNumberGenerator exposes simple static methods backed by the OS cryptographic random source.

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

public static class PasswordGenerator
{
    private const string Upper   = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private const string Lower   = "abcdefghijklmnopqrstuvwxyz";
    private const string Digits  = "0123456789";
    private const string Symbols = "!@#$%^&*()-_=+[]{}";

    public static string Generate(int length = 20, bool upper = true, bool lower = true,
                                   bool digits = true, bool symbols = true)
    {
        var pools = new System.Collections.Generic.List<string>();
        if (upper)   pools.Add(Upper);
        if (lower)   pools.Add(Lower);
        if (digits)  pools.Add(Digits);
        if (symbols) pools.Add(Symbols);
        if (pools.Count == 0) throw new ArgumentException("Select at least one character type");

        string fullPool = string.Concat(pools);
        var chars = new char[length];

        for (int i = 0; i < pools.Count; i++)
            chars[i] = pools[i][RandomNumberGenerator.GetInt32(pools[i].Length)];

        for (int i = pools.Count; i < length; i++)
            chars[i] = fullPool[RandomNumberGenerator.GetInt32(fullPool.Length)];

        // Fisher-Yates shuffle using the same secure source
        for (int i = chars.Length - 1; i > 0; i--)
        {
            int j = RandomNumberGenerator.GetInt32(i + 1);
            (chars[i], chars[j]) = (chars[j], chars[i]);
        }

        return new string(chars);
    }
}

// Console.WriteLine(PasswordGenerator.Generate(20));
// e.g. "k7$Rt2Xz!mQ9wLp#4vNc"

The Wrong Way (Don't Do This)

Never use System.Random for passwords, tokens, or cryptographic keys. The .NET documentation itself states it is not suitable for security-sensitive applications.
csharp โ€” insecure, do not use
// INSECURE โ€” System.Random is not cryptographically secure
var random = new Random();
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var password = new string(Enumerable.Range(0, 16)
    .Select(_ => chars[random.Next(chars.Length)]).ToArray());

Common Mistakes

Frequently Asked Questions

System.Random is a deterministic PRNG meant for general-purpose use. Microsoft's own documentation states it should not be used for security-sensitive applications. Use System.Security.Cryptography.RandomNumberGenerator instead.

It still functions but is considered legacy. Since .NET 6, the static methods on RandomNumberGenerator (like GetInt32 and Fill) provide the same security with a simpler API and are the current recommended approach.

Not recommended. Its format includes fixed hyphens and reserved version/variant bits, which reduce effective entropy compared with a password generator that uses the full character space you intend.

Prefer not to write the code?

Generate a strong password instantly in your browser.

Use the Password Generator โ†’

Related