bcrypt vs Argon2: как выбрать настройки хеширования паролей
bcrypt vs Argon2: сравнение безопасности, реальные затраты производительности и как выбирать безопасные параметры для современных веб-бэкендов.

Какую проблему решает хеширование паролей
Хеширование паролей позволяет бэкенду хранить не сам пароль, а его однонаправленную производную — хеш. При регистрации сервер прогоняет пароль через однонаправленную функцию и сохраняет результат. При входе он хеширует введённый пароль и сравнивает с сохранённым значением.
Хеш — это не шифрование. Его нельзя расшифровать. Именно это однонаправленное свойство и делает хеширование подходящим для паролей.
Так почему бы не использовать обычный быстрый хеш вроде SHA-256? Потому что «быстро» — это то, чего хотят атакующие. Если база данных украдена, злоумышленники не будут угадывать пароли по одному, отправляя запросы на логин. Они делают офлайн-перебор по списку хешей, насколько быстро позволяет их железо. С GPU быстрые хеши тестируются в огромных объёмах. Даже при уникальных солях быстрый хеш остаётся дешёвым для перебора.
Реалистичный сценарий провала: небольшое веб-приложение теряет таблицу пользователей в утечке. У злоумышленника есть почты и хеши паролей. Если хеши сделаны быстрой функцией, распространённые пароли и небольшие их вариации будут вскрыты быстро. Затем злоумышленник может попробовать те же пароли на других сайтах (credential stuffing) или получить доступ к привилегированным функциям внутри вашего приложения.
Хороший хеш делает перебор дорогим. Цель не в «неподвластности взлому», а в том, чтобы перебор был «слишком медленным и дорогим, чтобы окупиться».
Настройка хеширования паролей должна обеспечивать:
- однонаправленность (проверка, а не восстановление)
- замедление каждой попытки угадывания
- сопротивление параллельному аппаратному ускорению (особенно GPU)
- достаточную скорость, чтобы реальные входы казались нормальными
- возможность повышать стоимость с течением времени
bcrypt и Argon2 за одну минуту
Когда вы сравниваете bcrypt и Argon2, вы выбираете способ замедлить перебор паролей после утечки базы.
bcrypt — более старый и широко поддерживаемый вариант. Он заточен на нагрузку CPU и имеет один главный регулятор: фактор стоимости. Он «скучный» в хорошем смысле: легко доступен в библиотеках, просто разворачивается и предсказуем.
Argon2 — новее и спроектирован как memory-hard. Он может заставить каждую попытку угадывания требовать заметный объём оперативной памяти, а не только CPU. Это важно, потому что атакующие зачастую выигрывают за счёт большого числа параллельных попыток на GPU или специализированном железе. Масштабирование памяти при такой параллельности дороже и сложнее.
Argon2 имеет три варианта:
- Argon2i: фокус на устойчивость к некоторым побочным каналам
- Argon2d: фокус на сопротивлении GPU с другими соображениями по побочным каналам
- Argon2id: практичный микс обоих подходов и распространённый дефолт для хеширования паролей
Если ваш стек поддерживает Argon2id и вы можете безопасно настраивать память, это обычно лучший современный выбор. Если нужна максимальная совместимость со старыми системами, bcrypt остаётся надёжным выбором при корректной настройке фактором стоимости.
Важные свойства безопасности
Главный вопрос прост: если злоумышленник украдёт базу паролей, насколько дорого ему угадывать пароли в масштабе?
С bcrypt вы контролируете стоимость (work factor). Чем выше фактор, тем дольше занимает одна попытка. Это замедляет атакующих, но также замедляет и ваши проверки входа, поэтому вы настраиваете его так, чтобы было больно для атакующего, но терпимо для пользователя.
С Argon2id вы добавляете к временному фактору ещё и потребление памяти. Каждая попытка потребует CPU-времени и доступа к RAM в определённом паттерне. GPU очень хороши в вычислениях, но теряют преимущество, когда каждая параллельная попытка требует значительного объёма памяти.
Соли — обязательно. Уникальная случайная соль для каждого пароля:
- предотвращает повторное использование заранее вычисленных таблиц по базе
- гарантирует, что одинаковые пароли у разных пользователей дают разные хеши
Соль не делает слабые пароли сильными — она защищает после утечки, заставляя атакующих выполнять реальную работу для каждого пользователя.
Сильные и слабые стороны bcrypt
bcrypt остаётся широко используемым, главным образом из-за широкой доступности и простоты. Он хорошо подходит, когда нужна совместимость, ограниченные криптографические опции в стеке или одна простая ручка настройки.
Главный подводный камень — ограничение в 72 байта. bcrypt использует только первые 72 байта пароля и игнорирует остальное. Это может удивить людей, использующих длинные фразовые пароли или менеджеры паролей.
Если вы выбираете bcrypt, сделайте поведение с длиной пароля явным. Либо ограничьте длину (в байтах, а не в символах), либо последовательно обрабатывайте длинные вводы во всех сервисах. Главное — избегать молчащего усечения, которое меняет то, что пользователь считает своим паролем.
bcrypt также хуже сопротивляется современному параллельному взлому, чем memory-hard варианты. Его защита по-прежнему актуальна, но опирается на выбранный фактор стоимости, который должен держать каждую попытку дорогой.
Если вы строите новую систему или у вас есть аккаунты с высокой ценностью (платные планы, админские роли), распространённая и низкорисковая стратегия — хранить новые хеши в Argon2id, одновременно продолжая принимать старые bcrypt-хеши до тех пор, пока пользователи не войдут в систему и не будут обновлены.
Сильные стороны и компромиссы Argon2
Argon2 создан специально для хеширования паролей. Argon2id — вариант, который большинство команд выбирают как баланс между сопротивлением GPU и защитой от побочных каналов.
Argon2id даёт три параметра:
- Память (m): сколько RAM используется для одного хеша во время работы
- Время/итерации (t): сколько проходов по памяти выполняется
- Параллелизм (p): сколько «дорожек» используется (помогает на многоядерных CPU)
Память — главный бонус. Если каждая попытка требует значительного объёма RAM, атакующие не смогут запускать столько параллельных попыток без больших затрат на память и её пропускную способность.
Минус — операционный: больше памяти на хеш означает меньше одновременных логинов, которые ваши серверы могут обработать, прежде чем начнутся очереди или ошибки OOM. Если вы установите память слишком большой, всплески логинов могут вызвать ожидания, таймауты или падения серверов. Также думайте об абузе: много параллельных попыток входа может стать проблемой ресурсов без лимитов.
Чтобы Argon2id был безопасен и удобен в эксплуатации, настраивайте его как характеристику производительности:
- бенчмарьте на железе, похожем на продакшен
- ограничивайте конкурентную работу по хешированию (пулы воркеров, очереди)
- ограничивайте частоту входов и блокируйте повторяющиеся неудачи
- держите настройки консистентными между сервисами, чтобы слабый эндпоинт не стал целью
Затраты на производительность в реальных веб-бэкендах
С хешированием паролей цель «быстрее — лучше» обычно неверна. Вы хотите, чтобы каждая попытка была дорогой для атакующих, а входы оставались отзывчивыми для реальных пользователей.
Практичный подход — задать временной бюджет на проверку на вашем реальном оборудовании. Многие команды нацеливаются примерно на 100–300 мс на проверку хеша, но правильное значение зависит от трафика и серверов. Разница между bcrypt и Argon2 — в том, за что вы платите: bcrypt в основном тратит CPU, Argon2 может также резервировать память.
Выберите целевое время и измерьте
Выберите целевое время проверки и протестируйте в условиях, приближённых к продакшену. Измеряйте и регистрацию/смену пароля, и проверку при входе, но вход — это горячая дорожка.
Лёгкий план измерений:
- протестируйте 1, 10 и 50 конкурентных проверок входа и зафиксируйте p50 и p95 задержки
- повторите прогон, чтобы снизить шум от кэшей и динамики CPU
- измеряйте вызовы к базе отдельно, чтобы понять реальную стоимость хеширования
- тестируйте в тех же контейнерах и с теми же лимитами CPU, что и деплой
Всплески важнее средних значений
Большинство систем ломаются в пиках. Если маркетинговое письмо приводит волну пользователей на страницу входа, ваши настройки хеширования решают, останется ли система отзывчивой.
Если одна проверка занимает 250 мс и сервер может одновременно обрабатывать 40 таких проверок до очереди, волна в 500 попыток приведёт к многосекундным задержкам. В этом случае небольшое снижение стоимости вместе с жёсткими лимитами частоты может повысить реальную безопасность лучше, чем установка параметров настолько высоко, что точка входа становится хрупкой.
Делайте интерактивный вход предсказуемым
Не все операции с паролем имеют одинаковую срочность. Стабильность стоимости интерактивного входа важна; тяжёлую работу можно выносить из критического пути. Распространённый паттерн — rehash-on-login (обновление хеша сразу после успешного входа) или фоновые задания для миграций и импортов.
Как выбрать параметры пошагово
Тонкая настройка — это повышение стоимости для атакующего без замедления входов или дестабилизации серверов.
-
Выберите алгоритм, который хорошо поддерживается в вашем стеке. Если Argon2id доступен и надёжно поддерживается, он обычно дефолт. Если нужна совместимость, bcrypt подойдёт.
-
Задайте целевое время на хеш на железе, похожем на продакшен. Выберите значение, которое сохраняет отзывчивость во время пиков.
-
Настройте параметры, чтобы попасть в это время. Для bcrypt меняйте фактор стоимости. Для Argon2id балансируйте память, итерации и параллелизм. Память — тот рычаг, который сильнее всего меняет экономику атаки.
-
Храните алгоритм и настройки вместе с хешем. Большинство форматов хешей включает эти детали. Убедитесь, что поле в базе достаточно длинное, чтобы хеши не усекались.
-
Планируйте обновления через rehash-on-login. Когда пользователь входит, если его хеш старый или слабее текущей политики, пересчитайте и замените.
Практическое отправное значение
Если нужно быстро начать, начните консервативно и корректируйте по замерам.
- Для bcrypt многие команды стартуют с фактора 12 и корректируют по реальным измерениям.
- Для Argon2id распространённое стартовое значение — память в десятках или сотнях мегабайт, время 2–4 прохода, параллелизм 1–2.
Рассматривайте эти значения как отправные точки, а не правила. Правильные настройки зависят от трафика, железа и пиковой нагрузки.
Частые ошибки, которые ослабляют хранение паролей
Большинство ошибок связаны с пробелами в настройке, а не с «сломавшимся» алгоритмом.
Ошибки с солью. Каждому паролю нужна своя уникальная соль, сохранённая вместе с хешем. Повторное использование соли или одна общая соль для всех пользователей облегчает злоумышленнику повторное использование вычислений и сравнение аккаунтов.
Игнорирование фактора стоимости. Команды часто выпускают продукт с низким фактором, потому что входы кажутся быстрее, и потом никогда это не пересматривают. Железо растёт, атаки масштабируются, и прежние настройки становятся дешёвыми.
Перетюн памяти у Argon2. Слишком большая память выглядит хорошо на бумаге, но на практике вызывает медленные входы, очереди или OOM в пиках.
Обработка длины паролей. Это особенно важно для bcrypt — если вы разрешаете длинные пароли, но молча усекаете их, вы создаёте путаницу и снижаете безопасность.
Практические привычки, которые всё решают:
- используйте уникальные соли для каждого пароля (пускай библиотека генерирует их)
- нагрузочно тестируйте и пересматривайте настройки регулярно
- настраивайте память Argon2 под пик трафика, а не только под одиночные бенчмарки
- делайте ограничения по длине пароля явными и последовательными
- ставьте лимиты конкуренции и мониторинг на точку входа
Короткий чеклист для более безопасной настройки
Держите этот список при себе при релизе и при изменениях инфраструктуры:
- Уникальная соль на каждый пароль, генерация случайным способом и хранение с хешем
- Стоимость хеширования, выдерживающая пик нагрузки, проверенная нагрузочными тестами на оборудовании, похожем на продакшен
- Параметры, хранимые вместе с хешем, чтобы можно было верифицировать старые аккаунты и повышать стоимость позже
- Контроли онлайн-атак, включая лимиты частоты и короткие блокировки при повторных неудачах
- Путь обновления, обычно через rehash-on-login
Простой sanity-check: в staging устроьте всплеск входов (успешных и неуспешных) и смотрите на общую задержку, загрузку CPU и RAM. Если путь входа страдает, настройте стоимость и ужесточите лимиты. Не «исправляйте» проблему удалением солей.
Реалистичный пример: настройка для небольшого веб-приложения
Представьте небольшое SaaS-приложение с несколькими тысячами пользователей. В течение дня нагрузка обычно стабильна, но бывают короткие всплески входов после рассылки или в начале рабочего дня. Здесь выбор — это прежде всего планирование ёмкости.
Вы выбираете Argon2id, чтобы повысить стоимость офлайн-перебора. Задайте целевое время проверки на реальном сервере (например, 100–250 мс), затем настройте параметры так, чтобы попадать в это время, контролируя использование RAM, потому что настройки памяти ограничивают число одновременных входов.
Практический цикл настройки:
- начните с умеренных итераций и параллелизма
- увеличивайте память до тех пор, пока конкуррентность не станет неудобной
- подправляйте итерации, чтобы точно попасть в целевое время
- тестируйте со смоделированными всплесками, а не только одиночными запросами
Если у вас уже есть старые хеши с более слабыми настройками, продолжайте их верифицировать и тихо обновлять: при успешном входе пересчитайте хеш текущими параметрами и сохраните новый. Со временем активные пользователи перейдут на более сильные хеши без принудительных сбросов пароля.
После релиза мониторьте вход как критическую точку: tail latency (p95/p99), загрузку CPU и RAM в пиках, всплески неудачных входов и скорость замены старых хешей.
Следующие шаги: выпустите безопасно и улучшайте со временем
Запишите политику и относитесь к ней как к живому документу. Например: «Argon2id с X памяти, Y итераций, Z параллелизма» или «bcrypt фактор стоимости N», плюс дата выбора и срок пересмотра (каждые 6–12 месяцев — хорошая начальная частота).
Держите путь обновления, чтобы не застрять со старыми хешами. Rehash-on-login прост и работает в большинстве систем.
Сильный хеш — это важно, но он не заменяет контроли для онлайн-абуза. Лимиты частоты, блокировки и аккуратные потоки сброса пароля столь же важны для реальной безопасности.
Если вы строите бэкенд на no-code платформе вроде AppMaster, проверьте, что модуль аутентификации использует стойкие настройки хеширования по умолчанию и что стоимость хеширования настроена на том же типе инфраструктуры, где вы будете деплоить. Небольшое раннее тестирование часто решает вопрос между «безопасно и удобно» и «безопасно, но неработоспособно под нагрузкой».
Вопросы и ответы
Хеширование паролей позволяет проверять вход без хранения самого пароля. Вы сохраняете однонаправленный хеш, затем хешируете введённый пользователем пароль и сравниваете результаты; если база данных утекла, злоумышленникам всё равно придётся угадывать пароли, а не читать их.
Шифрование обратимо при наличии ключа, поэтому при компрометации ключа пароли можно восстановить. Хеширование по дизайну однонаправленное, и хранилище нельзя «расшифровать» обратно в оригинальный пароль.
Быстрые хеши хороши для многих задач, но они удобны и для атакующих: офлайн-перебор с GPU позволяет проверять миллионы вариантов в секунду. Для паролей нужен преднамеренно медленный (и желательно ещё и требующий памяти) хеш, чтобы массовый перебор стал дорогим.
Соль — это уникальное случайное значение, хранящееся рядом с каждым хешем. Она не даёт одинаковым паролям иметь одинаковые хеши и предотвращает использование заранее вычисленных таблиц; однако соль сама по себе не делает слабые пароли сильными.
Выбирайте Argon2id, если ваш стек его хорошо поддерживает и вы можете безопасно настраивать использование памяти — он создан, чтобы противостоять параллельным атакам. Выбирайте bcrypt, если нужна максимальная совместимость и простая модель настройки; в этом случае задайте достаточно высокий фактор стоимости.
У bcrypt есть ограничение в 72 байта: он использует только первые 72 байта пароля и игнорирует остальное. Чтобы избежать сюрпризов, явно ограничьте длину пароля в байтах или обрабатывайте длинные входы последовательно, чтобы не было молчащего усечения.
Параметр памяти у Argon2id — главный рычаг, потому что он ограничивает, сколько параллельных попыток смогут запускать атакующие без значительных затрат на RAM и пропускную способность. Слишком много памяти может навредить вам, уменьшив число одновременных входов, поэтому настраивайте под пик трафика, а не под единичные тесты.
Стремитесь к предсказуемому времени проверки на вашем реальном окружении, часто в районе 100–300 мс на проверку, затем нагрузочно тестируйте конкуррентность. Правильная настройка — та, что остаётся отзывчивой во время всплесков входов и при этом делает офлайн-перебор дорогостоящим.
Храните алгоритм и его параметры вместе с хешем, чтобы можно было проверять старые записи и повышать стоимость позже. Частый подход — rehash-on-login: после успешного входа, если текущие параметры слабее политики, пересчитайте хеш и сохраните его заново.
Чаще всего ошибки в хранении паролей связаны не с выбором алгоритма, а с конфигурацией: отсутствие уникальных солей, низкий фактор стоимости, который не пересматривается, и чрезмерный аптюннинг памяти Argon2 до уровня, когда входы начинают таймаутиться. Также следите за обработкой длины паролей (особенно для bcrypt) и защищайте точку входа лимитами частоты и короткими блокировками.


