Перейти к основному содержимому

Генератор случайных паролей на C#

Генератор случайных паролей на C#

Генератор случайных паролей — это утилита, создающая строки с заданными криптографическими свойствами: длина, наличие заглавных и строчных букв, цифр, специальных символов. Такой инструмент полезен при регистрации на сайтах, создании тестовых учётных записей или автоматизации задач безопасности.


Базовая реализация

Простейший генератор использует класс Random и набор допустимых символов:

using Система;
using Система.Text;

public class SimplePasswordGenerator
{
private static readonly string DefaultCharset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()";

public static string Generate(int length = 12)
{
if (length <= 0) throw new ArgumentException("Длина пароля должна быть положительной.");

Random random = new();
StringBuilder password = new(length);

for (int i = 0; i < length; i++)
{
int index = random.Next(DefaultCharset.Length);
password.Append(DefaultCharset[index]);
}

return password.ToString();
}
}

// Пример использования
class Program
{
static void Main()
{
string password = SimplePasswordGenerator.Generate(16);
Console.WriteLine($"Сгенерированный пароль: {password}");
}
}

Эта реализация проста, но имеет ограничения:

  • Использует предсказуемый генератор Random, не подходящий для криптографических целей.
  • Не гарантирует наличие всех типов символов (например, может не включить цифры).

Безопасная реализация с криптографической стойкостью

Для генерации надёжных паролей применяется RandomNumberGenerator, входящий в состав Система.Безопасность.Cryptography. Он использует источники энтропии операционной системы.

using Система;
using Система.Linq;
using Система.Безопасность.Cryptography;
using Система.Text;

public class SecurePasswordGenerator
{
private const string Lowercase = "abcdefghijklmnopqrstuvwxyz";
private const string Uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private const string Digits = "0123456789";
private const string Special = "!@#$%^&*()_+-=[]{}|;:,.<>?";

public static string Generate(
int length = 12,
bool includeLowercase = true,
bool includeUppercase = true,
bool includeDigits = true,
bool includeSpecial = true)
{
if (length <= 0) throw new ArgumentException("Длина пароля должна быть положительной.");

StringBuilder charsetBuilder = new();
if (includeLowercase) charsetBuilder.Append(Lowercase);
if (includeUppercase) charsetBuilder.Append(Uppercase);
if (includeDigits) charsetBuilder.Append(Digits);
if (includeSpecial) charsetBuilder.Append(Special);

string charset = charsetBuilder.ToString();
if (string.IsNullOrEmpty(charset))
throw new InvalidOperationException("Набор символов не может быть пустым.");

// Гарантируем наличие хотя бы одного символа из каждого выбранного класса
StringBuilder password = new();
RandomNumberGenerator rng = RandomNumberGenerator.Create();

if (includeLowercase) password.Append(GetRandomChar(rng, Lowercase));
if (includeUppercase) password.Append(GetRandomChar(rng, Uppercase));
if (includeDigits) password.Append(GetRandomChar(rng, Digits));
if (includeSpecial) password.Append(GetRandomChar(rng, Special));

// Добавляем оставшиеся символы из общего набора
while (password.Length < length)
{
password.Append(GetRandomChar(rng, charset));
}

// Перемешиваем символы, чтобы гарантированные символы не оказались в начале
return ShuffleString(password.ToString(), rng);
}

private static char GetRandomChar(RandomNumberGenerator rng, string source)
{
byte[] randomNumber = new byte[4];
rng.GetBytes(randomNumber);
uint randomValue = BitConverter.ToUInt32(randomNumber, 0);
int index = (int)(randomValue % source.Length);
return source[index];
}

private static string ShuffleString(string input, RandomNumberGenerator rng)
{
char[] array = input.ToCharArray();
for (int i = array.Length - 1; i > 0; i--)
{
byte[] randomNumber = new byte[4];
rng.GetBytes(randomNumber);
uint randomValue = BitConverter.ToUInt32(randomNumber, 0);
int j = (int)(randomValue % (i + 1));
(array[i], array[j]) = (array[j], array[i]);
}
return new string(array);
}
}

// Пример использования
class Program
{
static void Main()
{
string password = SecurePasswordGenerator.Generate(
length: 16,
includeLowercase: true,
includeUppercase: true,
includeDigits: true,
includeSpecial: true
);
Console.WriteLine($"Безопасный пароль: {password}");
}
}

Расширенная версия с настройками через объект

Для удобства можно обернуть параметры в отдельный класс:

public class PasswordOptions
{
public int Length { get; set; } = 12;
public bool IncludeLowercase { get; set; } = true;
public bool IncludeUppercase { get; set; } = true;
public bool IncludeDigits { get; set; } = true;
public bool IncludeSpecial { get; set; } = true;
public string CustomSpecialChars { get; set; } = "!@#$%^&*()_+-=[]{}|;:,.<>?";
}

public class AdvancedPasswordGenerator
{
public static string Generate(PasswordOptions options)
{
if (options.Length <= 0)
throw new ArgumentException("Длина пароля должна быть положительной.");

string lowercase = "abcdefghijklmnopqrstuvwxyz";
string uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string digits = "0123456789";
string special = options.CustomSpecialChars;

StringBuilder charsetBuilder = new();
if (options.IncludeLowercase) charsetBuilder.Append(lowercase);
if (options.IncludeUppercase) charsetBuilder.Append(uppercase);
if (options.IncludeDigits) charsetBuilder.Append(digits);
if (options.IncludeSpecial && !string.IsNullOrEmpty(special))
charsetBuilder.Append(special);

string charset = charsetBuilder.ToString();
if (string.IsNullOrEmpty(charset))
throw new InvalidOperationException("Набор символов не может быть пустым.");

StringBuilder password = new();
RandomNumberGenerator rng = RandomNumberGenerator.Create();

if (options.IncludeLowercase) password.Append(GetRandomChar(rng, lowercase));
if (options.IncludeUppercase) password.Append(GetRandomChar(rng, uppercase));
if (options.IncludeDigits) password.Append(GetRandomChar(rng, digits));
if (options.IncludeSpecial && !string.IsNullOrEmpty(special))
password.Append(GetRandomChar(rng, special));

while (password.Length < options.Length)
{
password.Append(GetRandomChar(rng, charset));
}

return ShuffleString(password.ToString(), rng);
}

// Методы GetRandomChar и ShuffleString — как в предыдущем примере
}

Использование:

var options = new PasswordOptions
{
Length = 20,
IncludeSpecial = true,
CustomSpecialChars = "!@#"
};

string pwd = AdvancedPasswordGenerator.Generate(options);
Console.WriteLine(pwd);

Особенности реализации

  • Криптографическая безопасность: используется RandomNumberGenerator, а не Random.
  • Гарантированное содержание символов: если включён определённый класс символов, он обязательно присутствует в результате.
  • Перемешивание: предотвращает предсказуемое расположение обязательных символов.
  • Гибкость: поддержка пользовательских наборов специальных символов.
  • Валидация входных данных: проверка корректности длины и непустоты набора символов.

См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).