Короткий ответ
Хранение пароля в открытом виде или через быстрый хеш без соли делает базу уязвимой к мгновенной компрометации всех учётных записей при утечке; специализированные алгоритмы (bcrypt, argon2) с солью и настраиваемой стоимостью вычислений делают подбор пароля экономически невыгодным.
Как это работает подробнее
Соль — случайная строка, уникальная для каждого пользователя, добавляемая к паролю перед хешированием, что делает бесполезными заранее посчитанные радужные таблицы. bcrypt/argon2 дополнительно намеренно медленные и настраиваемые по «cost factor», в отличие от MD5/SHA-256, которые проектировались быстрыми.
Пример кода
example.py
import bcrypt
password = b"super-secret-password"
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
# hashed уже содержит соль внутри строки, отдельно хранить её не нужно
assert bcrypt.checkpw(b"super-secret-password", hashed) is True
assert bcrypt.checkpw(b"wrong-password", hashed) is FalseЧто использовать на практике
- Практика. В Python для этого используют библиотеки passlib, bcrypt или встроенные механизмы фреймворка (Django использует PBKDF2/argon2 по умолчанию); соль генерируется автоматически и хранится вместе с хешем в одной строке.
Подводные камни
- Риск. Пишут собственную схему хеширования «для скорости»; сравнивают хеши через обычный
==вместо constant-time сравнения, что теоретически открывает timing-атаку; хранят пароли в логах при отладке.