/
denispirit
/
informationSystem
Обзор
Документация
Войти
/
denispirit
/
informationSystem
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
InformationSystem/PasswordHasher.cs
70 строк
5 KB
denispirit
Первый коммит. Отправка в репозиторий
29 сен 2025, 10:39
29 сен 2025, 10:39
24ca85c
Код
Авторство
О чём код?
using System; // Импорт пространства имен System для базовых классов .NET using System.Security.Cryptography; // Импорт для криптографических функций namespace InformationSystem // Объявление пространства имен приложения { internal class PasswordHasher // Объявление внутреннего класса для хеширования паролей { // Константы для настройки параметров хеширования private const int SaltSize = 16; // Объявление константы размера соли - 16 байт (128 бит) private const int HashSize = 32; // Объявление константы размера хеша - 32 байта (256 бит) private const int Iterations = 10000; // Объявление константы количества итераций PBKDF2 // Метод для хеширования пароля public static (string Hash, string Salt) HashPassword(string password) // Объявление статического метода, возвращающего кортеж { // Генерируем случайную соль byte[] salt = new byte[SaltSize]; // Создание массива байтов для соли указанного размера using (var rng = RandomNumberGenerator.Create()) // Создание криптографически безопасного генератора случайных чисел { rng.GetBytes(salt); // Заполнение массива соли случайными байтами } // Генератор автоматически освобождается благодаря using // Создаем хеш пароля byte[] hash = PBKDF2(password, salt, Iterations, HashSize); // Вызов метода PBKDF2 для создания хеша return (Convert.ToBase64String(hash), Convert.ToBase64String(salt)); // Возврат хеша и соли в формате Base64 } // Конец метода HashPassword // Метод для проверки пароля public static bool VerifyPassword(string password, string storedHash, string storedSalt) // Объявление метода проверки пароля { try // Начало блока обработки исключений { // Декодируем соль и хеш из Base64 byte[] salt = Convert.FromBase64String(storedSalt); // Декодирование соли из строки Base64 в массив байтов byte[] hash = Convert.FromBase64String(storedHash); // Декодирование хеша из строки Base64 в массив байтов // Вычисляем хеш введенного пароля byte[] testHash = PBKDF2(password, salt, Iterations, HashSize); // Создание хеша для проверки // Сравниваем хеши безопасным способом return SlowEquals(hash, testHash); // Возврат результата безопасного сравнения хешей } // Конец блока try catch // Обработка любых исключений { return false; // Возврат false при возникновении ошибки } // Конец блока catch } // Конец метода VerifyPassword // Приватный метод для реализации PBKDF2 private static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes) // Объявление приватного метода PBKDF2 { using (var pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations, HashAlgorithmName.SHA256)) // Создание объекта PBKDF2 { return pbkdf2.GetBytes(outputBytes); // Генерация и возврат хеша указанного размера } // Объект автоматически освобождается } // Конец метода PBKDF2 // Метод для безопасного сравнения массивов байтов private static bool SlowEquals(byte[] a, byte[] b) // Объявление метода безопасного сравнения { uint diff = (uint)a.Length ^ (uint)b.Length; // Вычисление XOR длин массивов (0 если равны) for (int i = 0; i < a.Length && i < b.Length; i++) // Цикл по элементам массивов { diff |= (uint)(a[i] ^ b[i]); // Накопление различий через оператор OR } // Конец цикла for return diff == 0; // Возврат true если различий нет (diff == 0) } // Конец метода SlowEquals } // Конец класса PasswordHasher } // Конец пространства имен InformationSystem