Как безопасно хранить пароль пользователя в базе данных?

«Как безопасно хранить пароль пользователя в базе данных?» — вопрос из категории Безопасность, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Пароли никогда не должны храниться в открытом виде. Стандартный и безопасный подход — хеширование с использованием специальных, медленных алгоритмов, устойчивых к перебору (брутфорсу).

Основные шаги:

  1. Использовать специализированную функцию хеширования паролей:
    • Argon2id — современный победитель конкурса PHC, рекомендуется для новых систем.
    • bcrypt — проверенный временем, широко поддерживаемый алгоритм.
    • PBKDF2 (с достаточным числом итераций, например, >100k) — часто встроен в стандартные библиотеки.
  2. Добавлять уникальную "соль" (salt) для каждого пароля. Это предотвращает атаки по радужным таблицам и делает хеши уникальными, даже если пароли совпадают.
  3. Хранить в БД только результат хеширования (хеш), соль и параметры алгоритма (например, стоимость, фактор итераций).

Пример на C# с использованием BCrypt.Net-Next:

using BCrypt.Net;

// Регистрация пользователя: ХЕШИРОВАНИЕ ПАРОЛЯ
string passwordFromUser = "user_password_123";
// WorkFactor (по умолчанию 11) определяет сложность вычисления.
string passwordHash = BCrypt.EnhancedHashPassword(passwordFromUser, HashType.SHA512, workFactor: 12);
// passwordHash выглядит как "$2a$12$s4BvzY7P8eNnT3wUQfLkOe9..." и содержит соль и параметры.
// Сохраняем `passwordHash` в поле `Users.PasswordHash` в БД.

// Аутентификация пользователя: ПРОВЕРКА ПАРОЛЯ
string attemptedPassword = "user_password_123";
string storedHash = GetHashFromDatabase(user.Id); // Получаем хеш из БД
bool isPasswordCorrect = BCrypt.EnhancedVerify(attemptedPassword, storedHash, HashType.SHA512);

Что НЕ делать:

  • ❌ Хранить пароли в открытом тексте.
  • ❌ Использовать быстрые криптографические хеш-функции (MD5, SHA-1, SHA-256) без специальных механизмов замедления.
  • ❌ Создавать свою реализацию криптоалгоритмов.