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

Ответ

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

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

  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) без специальных механизмов замедления.
  • ❌ Создавать свою реализацию криптоалгоритмов.

Ответ 18+ 🔞

А, слушай, про пароли. Это ж классика, про которую все знают, но половина всё равно наступает на одни и те же грабли, как слепой кот на крыльцо. Запомни раз и навсегда: пароли в открытом виде хранить — это уровень «админ: админ». Прям в рот мне чих-пых, ну кто так делает-то в двадцать каком-то году?

Смысл в чём? Надо их так запрятать, чтобы даже если у тебя всю базу данных вытащат, эти пидарасы не смогли ничего сделать. Не просто «зашифровать», а именно захешировать специальными, медленными алгоритмами. Чтобы подбор одного пароля на кластере из ста видеокарт занимал не секунды, а годы. Вот это — правильный путь.

Как делать надо, по шагам:

  1. Берёшь спецфункцию для паролей. Не какую попало, а именно ту, что создана, чтобы тянуть время.
    • Argon2id — это сейчас крутой новичок, чемпион. Бери его, если можешь.
    • bcrypt — старый, добрый, проверенный в тысячах драк. Работает — не трогай.
    • PBKDF2 — тоже норм, особенно если встроен в твою платформу, но итераций сделай побольше, тысяч сто, не меньше.
  2. Обязательно солишь. Это не про «посолить по вкусу», а про уникальную случайную строку для КАЖДОГО пароля. Чтобы если у двух юзеров пароль «123456», хеши были абсолютно разными. Иначе радужные таблицы сожрут твою базу на завтрак.
  3. В базу кладёшь только итог: сам хеш, соль (часто она уже внутри хеша) и параметры алгоритма (сложность, итерации). Исходный пароль — в топку, его даже ты не должен видеть.

Вот, смотри, как на C# с bcrypt это выглядит просто:

using BCrypt.Net;

// Когда пользователь регистрируется — хешируем его пароль
string userPassword = "мой_секретный_парольчик";
// WorkFactor (здесь 12) — это и есть «замедлитель». Чем больше, тем дольше считать, тем безопаснее.
string hashedPassword = BCrypt.EnhancedHashPassword(userPassword, HashType.SHA512, workFactor: 12);
// Получится строка типа "$2a$12$s4BvzY7P8eNnT3wUQfLkOe9...". Всё, сохраняй её в БД и спи спокойно.

// Когда логинится — проверяем
string passwordAttempt = "мой_секретный_парольчик";
string hashFromDB = GetHashFromDatabase(user.Id); // Достаём хеш из базы
bool isCorrect = BCrypt.EnhancedVerify(passwordAttempt, hashFromDB, HashType.SHA512);
// Всё, библиотека сама разберёт соль и проверит.

А теперь главное — что делать НЕ НАДО, а то волосы дыбом встанут:

  • Хранить пароли открытым текстом. Это даже не ошибка, это преступление. Серьёзно, тебя за это по рукам бить должны.
  • Использовать MD5, SHA-1 и прочие быстрые хеши. Они для паролей — что картонная дверь для взломщика. Брутфорс их щёлкает как орехи.
  • Изобретать свой велосипед. Не пиши свою крипту, не комбинируй алгоритмы через дефис, не выдумывай «супер-секретный метод». Возьми готовую, уважаемую библиотеку и не выёбывайся. Все умные люди до тебя уже всё придумали.

Вот и вся наука. Сделаешь так — спишь спокойно. Сделаешь иначе — однажды ночью получишь алерт, что твоя база уже торгуется на каком-нибудь форуме, и будешь потом объяснять, какого хуя.