Зачем пароли превращают в хэш и почему его нельзя расшифровать

«Всегда есть две базовые ошибки в понимании хэшей: думать, что это шифрование, или верить, что хороший хэш можно подобрать только за миллион лет. На самом деле современный безопасный хэш, это не функция для паролей. И когда пароль хранят в виде хэша, на самом деле это уже давно не просто хэш.»

Мы вводим пароль в форму и, кажется, что на другом конце он так и остаётся строкой символов. Никто не видит, что происходит внутри. А там целый алгоритм превращает ваш «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, вводят понятие вычислительной сложности (рабочего фактора). Они преднамеренно выполняют десятки или сотни тысяч итераций хэширования, потребляют много памяти, что делает массовый перебор экономически невыгодным даже на специализированном железе. Современные рекомендации, в том числе отечественные, прямо предписывают использовать подобные медленные функции, а не криптографические хэши напрямую.

Практический итог: как сейчас правильно хранить пароль

Современный безопасный процесс выглядит так:

  1. Генерация уникальной соли для каждого пароля.
  2. Применение медленной функции ключевого вывода (например, Argon2id) к связке «пароль + соль» с настраиваемыми параметрами сложности (время, память).
  3. Сохранение в базу данных тройки: идентификатора алгоритма, параметров сложности, соли и итогового ключа (derived key).

когда говорят «пароли хранят в виде хэша», на деле подразумевают именно этот многослойный процесс с использованием KDF, соли и высокой вычислительной стоимости. Простое хэширование устарело как метод защиты паролей более десяти лет назад.

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

Оставьте комментарий