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

Ответ

Пароли пользователей никогда не должны храниться в базе данных в открытом виде. Для их безопасного хранения используется одностороннее хеширование с добавлением "соли".

Процесс выглядит так:

  1. Генерация "соли" (Salt): Для каждого пользователя создается уникальная случайная строка — соль.
  2. Хеширование: Пароль пользователя объединяется с солью, и результат пропускается через криптографическую хеш-функцию.
  3. Хранение: В базе данных сохраняется только хеш и соль. Исходный пароль не хранится нигде.

Почему это безопасно?

  • Необратимость: Из хеша невозможно восстановить исходный пароль.
  • Защита от радужных таблиц: Соль гарантирует, что даже у пользователей с одинаковыми паролями будут абсолютно разные хеши, что делает предварительно вычисленные таблицы хешей (rainbow tables) бесполезными.

Рекомендуемые алгоритмы:

  • Argon2 (победитель конкурса Password Hashing Competition, современный стандарт)
  • bcrypt (очень надежный и широко используемый)
  • scrypt или PBKDF2

Важно: Следует избегать устаревших алгоритмов, таких как MD5 или SHA-1, так как они не являются безопасными для хранения паролей.

Пример на Python с bcrypt:

import bcrypt

# Пароль, полученный от пользователя при регистрации
password = b"S3cuRe_P@ssw0rd!"

# 1. Генерируем соль и создаем хеш
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password, salt)

# В БД сохраняем hashed_password (он уже содержит соль)
# print(hashed_password) -> b'$2b$12$....'

# --- Проверка пароля при входе ---

# Пароль, введенный пользователем
user_input = b"S3cuRe_P@ssw0rd!"

# 2. Сравниваем введенный пароль с хешем из БД
if bcrypt.checkpw(user_input, hashed_password):
    print("Пароль верный")
else:
    print("Пароль неверный")

Ответ 18+ 🔞

А, слушай, вот тебе история про то, как пароли хранить, чтобы потом не охуеть от последствий. Пароли пользователей, блядь, ни в коем случае нельзя просто так, по-распиздяйски, пихать в базу данных как есть, в открытом виде. Это как оставить ключи от квартиры под ковриком — только дурак так делает. Вместо этого используется штука под названием одностороннее хеширование с "солью", ёпта.

Как это, сука, работает:

  1. Генерация "соли" (Salt): Для каждого юзера, как снежинку, создаётся уникальная, случайная строка — вот эта самая соль. Хуй с горы угадает, какая.
  2. Хеширование: Берёшь пароль от пользователя, подсыпаешь туда эту самую соль, и всю эту смесь пропускаешь через криптографическую хеш-функцию. Получается такая каша, из которой назад не выудить нихуя.
  3. Хранение: В базу летит только этот самый хеш и соль. Сам пароль, блядь, нигде не лежит, его в помине нет. Словно его и не было.

А почему это, нахуй, безопасно?

  • Необратимость: Из этого хеша восстановить исходный пароль — это как из говна конфетку сделать, нихуя не выйдет.
  • Защита от радужных таблиц: Соль — это вообще гениально, блядь. Она делает так, что даже если два лоха поставят пароль "123456", хеши у них будут абсолютно разные, как небо и земля. Все эти предварительно вычисленные таблицы хешей (rainbow tables) становятся бесполезным хламом, в рот меня чих-пых!

Чем, сука, пользоваться?

  • Argon2 (этот вообще красавчик, победитель всех конкурсов, сейчас его в тренде пихать)
  • bcrypt (старый, добрый, проверенный временем, овердохуища проектов на нём стоят)
  • scrypt или PBKDF2 — тоже норм варианты.

Ваще, блядь, запомни: Избегай как огня устаревшего говна вроде MD5 или SHA-1. Их щас даже школьник может сломать. Это не для паролей, ёпта.

Смотри, как на Python с bcrypt это выглядит, чтоб ты понимал масштаб:

import bcrypt

# Пароль, который пользователь ввёл при регистрации
password = b"S3cuRe_P@ssw0rd!"

# 1. Генерируем соль и делаем из пароля этакую несъедобную хешированную котлету
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password, salt)

# В БД тащим именно hashed_password (он уже с солью внутри, хитрая жопа)
# print(hashed_password) -> b'$2b$12$....'

# --- А вот когда чел приходит логиниться ---

# Пароль, который он ввёл в форму
user_input = b"S3cuRe_P@ssw0rd!"

# 2. Сравниваем, что он ввёл, с тем, что у нас лежит в закромах
if bcrypt.checkpw(user_input, hashed_password):
    print("Пароль верный")
else:
    print("Пароль неверный")

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