«Всегда есть две базовые ошибки в понимании хэшей: думать, что это шифрование, или верить, что хороший хэш можно подобрать только за миллион лет. На самом деле современный безопасный хэш, это не функция для паролей. И когда пароль хранят в виде хэша, на самом деле это уже давно не просто хэш.»
Мы вводим пароль в форму и, кажется, что на другом конце он так и остаётся строкой символов. Никто не видит, что происходит внутри. А там целый алгоритм превращает ваш «SuperPass123» в нечитаемую строку. Это называется хешированием. Но это не шифрование, и это ключевая разница. Шифрование подразумевает ключ и возможность вернуть всё обратно — расшифровать. Хеширование — процесс односторонний. Вы не можете взять результат и получить исходную строку обратно. Это свойство и сделало хэширование основой для хранения паролей.
Чем хэш отличается от шифрования и зачем это нужно
Если представить данные как текст, то шифрование, это перемешивание букв по определённому правилу, известному обладателю ключа. С ключом всё можно восстановить. Хеширование же, это превращение текста в уникальный отпечаток фиксированной длины, своего рода «цифровой слепок». Восстановить исходный текст по этому отпечатку невозможно в принципе, так как в процессе часть информации теряется безвозвратно.
Именно эта необратимость и важна. Когда сервер получает ваш пароль при регистрации, он пропускает его через хэш-функцию и сохраняет только полученный хэш. При следующем входе система делает то же самое с введённым паролем и сравнивает уже хэши. Совпадают — доступ открыт. Серверу не нужно знать и хранить ваш исходный пароль. Таким образом, даже если злоумышленник получит доступ к базе данных с хэшами, у него не будет самих паролей.
Как работают хэш-функции: от простого CRC32 до стойкого SHA-256
Хэш-функции бывают разными. Некоторые создавались для скоростной проверки целостности данных, а другие — специально для криптографической защиты. Старые алгоритмы, такие как MD5 или SHA-1, больше не считаются криптографически стойкими. Их уязвимости позволяют находить коллизии — разные исходные данные, дающие одинаковый хэш.
Современные стандарты, такие как SHA-256 или SHA-3, спроектированы так, чтобы малейшее изменение во входных данных — даже один бит — приводило к совершенно другому, непредсказуемому хэшу. Это называется «лавинный эффект». Вот как выглядит разница на практике:
SHA256("пароль")даёт один результат.SHA256("паролЬ")(с заглавной Ь) — совершенно другую строку, не имеющую видимого сходства с первой.
Такая чувствительность гарантирует, что по хэшу нельзя сделать никаких предположений об исходном пароле.
Почему «просто хэша» уже недостаточно: атаки по словарям и радужные таблицы
Казалось бы, проблема решена. Однако необратимость хэша не означает его неуязвимости. Основные атаки направлены не на взлом функции, а на обход её логики.
- Атака по словарю: Злоумышленник берёт базу типичных паролей («123456», «qwerty», «password»), хэширует каждый и сравнивает с украденной базой хэшей. Совпадение означает найденный пароль.
- Радужные таблицы: Это оптимизированные предварительно вычисленные таблицы хэшей для миллионов, а иногда и миллиардов возможных паролей. Поиск по ним происходит очень быстро. Если пароль простой или распространённый, он почти наверняка будет в такой таблице.
Эти методы эффективны именно потому, что для одного и того же пароля хэш всегда одинаков. Это детерминированность — одновременно и необходимое свойство для проверки, и ахиллесова пята наивной реализации.
Соль и перец: как усложнить жизнь взломщику
Ответом на проблему предсказуемости стала «соль» (salt). Соль, это случайная строка, которая генерируется уникально для каждого пароля. Перед хэшированием она добавляется к паролю (или смешивается с ним). В базу данных сохраняются и сам хэш, и использованная соль.
// Пример логики (не реальный код)
saved_hash = SHA256(password + unique_salt)
// В базе хранится пара: saved_hash и unique_salt
Теперь для проверки система берёт введённый пароль, прибавляет к нему сохранённую соль из базы, хэширует и сравнивает результат с сохранённым хэшем.
Что это меняет? Радужные таблицы становятся бесполезными. Их нельзя подготовить заранее, так как для каждого пароля нужна своя уникальная соль. Атака по словарю превращается в трудоёмкую задачу перебора для каждого аккаунта отдельно. Соль не является секретом и хранится вместе с хэшем, её задача — не скрыть, а сделать атаки массовыми.
Существует и понятие «перца» (pepper) — секретного значения, добавляемого ко всем паролям, которое хранится отдельно от базы данных, например, в конфигурационном файле приложения. Это добавляет ещё один уровень защиты на случай компрометации только базы данных.
Ключевая функция вывода: почему современные системы используют не просто хэш
Даже солёный хэш, созданный с помощью быстрых алгоритмов вроде SHA-256, остаётся уязвимым к перебору на мощном GPU или специализированном ASIC-оборудовании. Злоумышленник, получив базу, может быстро пробовать миллиарды вариантов для каждого солёного пароля.
Поэтому для хранения парольных учётных данных была разработана специальная категория функций — функции ключевого вывода (Key Derivation Function, KDF). Их цель — целенаправленно сделать процесс получения ключа из пароля медленным и ресурсоёмким.
Популярные KDF, такие как PBKDF2, bcrypt, scrypt и Argon2, вводят понятие вычислительной сложности (рабочего фактора). Они преднамеренно выполняют десятки или сотни тысяч итераций хэширования, потребляют много памяти, что делает массовый перебор экономически невыгодным даже на специализированном железе. Современные рекомендации, в том числе отечественные, прямо предписывают использовать подобные медленные функции, а не криптографические хэши напрямую.
Практический итог: как сейчас правильно хранить пароль
Современный безопасный процесс выглядит так:
- Генерация уникальной соли для каждого пароля.
- Применение медленной функции ключевого вывода (например, Argon2id) к связке «пароль + соль» с настраиваемыми параметрами сложности (время, память).
- Сохранение в базу данных тройки: идентификатора алгоритма, параметров сложности, соли и итогового ключа (derived key).
когда говорят «пароли хранят в виде хэша», на деле подразумевают именно этот многослойный процесс с использованием KDF, соли и высокой вычислительной стоимости. Простое хэширование устарело как метод защиты паролей более десяти лет назад.
Понимание этой эволюции — от хэша к солёному хэшу, а от него к настраиваемой медленной функции — критически важно для проектирования систем, которые действительно защищают учётные данные пользователей, а не создают иллюзию безопасности.