Как надо хешировать пароли и как не надо / Хабр
В очередной раз, когда мы заканчивали проводить аудит информационной безопасности веб-проекта, моя личная бочка с гневом переполнилась негодованием так, что оно перелилось через край в этот пост.
Постараюсь очень лаконично и быстро обрисовать ситуацию с хэшами.
Сразу определю какую задачу применения хешей буду рассматривать — аутентификация пользователей. Не токены восстановления паролей, не аутентификация запросов, не что-то еще. Это также не статья про защиту канала передачи данных, так что комментарии по challenge-response и SSL неуместны!
Матчасть (короткая)
Hash = хеш функция — (свертка) функция однозначного отображения строки (любой длины) на конечное множество (строку заданной длины).
Само число (строка) хеш — результат вычисления хеш-функции над данными.
Существуют криптографические и некриптографические (классифицируются отдельно, к ним относятся, например, контрольные суммы) хеш-функции.
Для криптографических хэшей есть три дополнительных условия, которые отличают их от всех остальных:
- Необратимость: для заданного значения хеш-функции m должно быть вычислительно неосуществимо найти блок данных X, для которого H(X)=m.
- Стойкость к коллизиям первого рода: для заданного сообщения M должно быть вычислительно неосуществимо подобрать другое сообщение N, для которого H(N)=H(M).
- Стойкость к коллизиям второго рода: должно быть вычислительно неосуществимо подобрать пару сообщений ~(M, M’), имеющих одинаковый хеш
Подробнее — ru.wikipedia.org/wiki/%D0%A5%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5
Вникать в тонкости криптографии прикладному разработчику не обязательно, достаточно запомнить какие хэш-функции (алгоритмы по названию) можно сейчас использовать, а какие уже нет. MD5 — уже нельзя, коллеги, — используйте bcrypt/scrypt.
В веб-приложениях, в числе прочего, хеш-функции используются для безопасного хранения секретов (паролей) в базе данных.
Именно хэш-функция становится вашим последним оплотом, если злоумышленник смог свести нападение к локальной атаке на систему аутентификации. Про онлайн атаки (перебор паролей НТТР запросами), может быть, кто-то еще напишет позже.
Ниже перечислены требования, которым ваш хеш в базе должен удовлетворять:
- стойкость к атакам перебора (прямой перебор и перебор по словарю)
- невозможность поиска одинаковых паролей разных пользователей по хешам
Для выполнения первого требования нужно использовать стойкие в настоящее время (а не в 90х годах!) хеш-функции.
Для выполнения второго — к паролю перед хешированием добавляется случайная строка (соль). Таким образом, у двух пользователей с паролем «123456» будут разные соли «соль1» и «соль2», а соответственно и хеш-функции от «123456соль1» и «123456соль2» в базе тоже будут разные.
Теперь немного про систему хранения — и соль и сам хеш хранятся в базе данных.
То есть получив доступ к СУБД, злоумышленник получает и значения хешей и соли.
Используйте локальный параметр!
Чтобы усложнить жизнь при атаке перебора следует дописать соль к паролю, а не наоборот (для людей, которые пишут слева направо, конечно).
Так как хеш-функция, как правило, вычисляется последовательно по строке (требования поточности алгоритма), то злоумышленнику при переборе «соленых» хешей, будет проще, когда подхешовое выражение начинается с соли.
Для того чтобы еще усложнить жизнь атакующему, Solar Designer www.openwall.com/presentations/YaC2012-Password-Hashing-At-Scale/mgp00005.html предлагает ввести еще одну штуку, под названием локальный параметр.
Это по сути «вторая соль» дописывается ко всем (паролям+соль) конструкциям, и является одинаковой для всех хешей в базе.
Очень простая и действенная мера, которая позволяет практически полностью исключить атаку перебора по данным только одного хранилища хешей (без знания локального параметра).
Единственный раз мы (ONsec) ломали хеши с локальным параметром, выработав при этом тактику атаки на сам локальный параметр (регистрируемся в приложении, затем ищем в базе свой хеш, соль (свой пароль мы и так знаем) и перебираем ЛП). И тщетно. На длинах 16+ байт для современных функций хеширования — это очень дорого по железу. В итоге проще оказалось скомпрометировать систему аутентификации (проставить себе role=admin в базе через UPDATE 😉 )
Очень рекомендую ознакомиться с презентацией: www.openwall.com/presentations/YaC2012-Password-Hashing-At-Scale/mgp00001.html
Защищайте свои хранилища надежно и грамотно!
Заключение
Буду реалистом — естественно, никто не станет переписывать свои проекты ради «каких-то» хешей. Но новые проекты можно писать на scrypt/bcrypt. А также — внедряйте локальный параметр даже на слабых MD5 — он правда помогает, проверено 🙂
При переходе на другой тип хеширования, помимо трудозатрат, часто встает вопрос производительности. Действительно, более стойкие алгоритмы потребляют больше ресурсов. Тестируйтесь перед внедрением для своих нагрузок по скорости аутентификации пользователей в секунду (для большинства крупных проектов переход на scrypt оказался безболезненным). Выбор конкретного идеального типа хеша в конкретной ситуации может сильно разнится. Так, например, ДБО все чаще выбирают железные решения для генерации хешей с заданной скоростью.
В заключении, привожу скорости перебора хешей (единицы измерения — мегахэши в секунду, то есть количество ), полученных на карточке AMD Radeon 7990 стоимостью менее $1000 (даже по старому курсу):
- MD5: 16000 M/s
- SHA-1: 5900 M/s
- SHA256: 2050 M/s
- SHA512: 220 M/s
- NTLM: 28400 M/s
- bcrypt: 8,5 k/s
А по поводу эффективности перебора bcrypt рекомендую также ознакомиться с www. openwall.com/presentations/Passwords13-Energy-Efficient-Cracking/Passwords13-Energy-Efficient-Cracking.pdf
что это такое простыми словами
Хэш или хэш-функция – одна из основных составляющих современной криптографии и алгоритма блокчейна.
Хэширование представляет собой преобразование любого объема информации в уникальный набор символов, который присущ только этому массиву входящей информации. Этот набор символов и будет называться хэшем.
Свойства хэшаУ хэш-функции есть несколько обязательных свойств:
- Хэш всегда уникален для каждого массива информации. Однако иногда случаются так называемые коллизии, когда для разных входных блоков информации вычисляются одинаковые хэш-коды.
- При самом незначительном изменении входной информации ее хэш полностью меняется.
- Хэш-функция необратима и не позволяет восстанавливать исходный массив информации из символьной строки. Это можно сделать, только перебрав все возможные варианты, что при бесконечном количестве информации требует много времени и денег.
- Хэширование позволяет достаточно быстро вычислить нужный хэш для достаточно большого объема информации.
- Алгоритм работы хэш-функции, как правило, делается открытым, чтобы при необходимости можно было оценить ее стойкость к восстановлению начальных данных по выдаваемому хэшу.
- Хэш-функция должна уметь приводить любой объем данных к числу заданной длины.
Такой пример не часто встречается в реальной работе, но он наглядно показывает, насколько хэш-функция может облегчить работу с большими объемами информации.
Например, в массив из нескольких миллионов разных строк длиной 1 млн символов нужно добавить еще одну, при условии, что там ее еще нет. Чтобы не заниматься посимвольным сравнением каждой строки, можно предварительно вычислить хэш каждой из них, и уже сделать сравнение по нему. Вся работа упрощается и ускоряется в разы.
Проверка целостности данных при передачеДля таких проверок часто используются простые хэш-функции.
Например, один пользователь передает другому определенный массив данных, а затем хэш от него. Получатель информации, захэшировав информацию у себя и сравнив хэши, может удостовериться, что он получил именно те данные, которые были отправлены.
В технологии блокчейн хэш также используется для проверки целостности данных. Хэш выступает гарантией целостности цепочки транзакций (платежей) и защищает ее от несанкционированных изменений. Благодаря ему и распределенным вычислениям взломать блокчен очень сложно.
ШифрованиеНа практике некоторые хэш-функции также используются для шифрования. Благодаря практически полностью хаотичному соответствию хэшей исходным данным, практически невозможно вычислить начальный массив данных. Такие хэш-функции должны быть очень стойкими к коллизиям, т. е. должна обладать минимальной вероятностью получения двух одинаковых хэшей для двух разных массивов данных. Расчеты по таким алгоритмам более сложные и требует больше времени, но зато отличаются надежностью.
Электронные цифровые подписиИспользование хэша в данной технологии позволяет пользователю, который подписывает документ, быть уверенным, что он подписывает именно тот документ, который требуется. Также хэш используется при формировании электронной цифровой подписи и аутентификации пользователей.
Хранение паролейДля доступа к сайтам и серверам по логину и паролю тоже часто используют хэширование.
Пользователь регистрируется на сайте:
- Заполняет форму регистрации, включая поле Пароль,
- Пароль обрабатывается хэш-функцией и помещается в базу данных,
- Оригинальное значение пароля нигде не используется.
Пользователь входит на сайт:
- Вводит свой логин и пароль,
- Пароль хэшируется и сравнивается с данными базы,
- Если хэши совпадают, пользователя заходит на сайт.
Для такого типа хэширования, как правило, применяются сложные функции с очень высокой криптостойкостью, которые не позволяют подобрать пароль по хэшу.
Рейтинг 3.85, голосов 85 |
Что такое соленые пароли и хеширование паролей?
При создании приложений, ориентированных на клиентов, безопасность часто не имеет значения. Но в условиях постоянных утечек данных крупных корпораций, таких как T-Mobile и Google, компании должны проявлять бдительность, чтобы придерживаться передовых методов обеспечения безопасности.
Такие процессы, как добавление соли и хеширование паролей, имеют основополагающее значение для обеспечения безопасности ваших приложений. Понимание этих более широких концепций безопасности — первый шаг к тому, чтобы избежать серьезных нарушений базы данных и потери доверия потребителей.
В этом посте мы рассмотрим основы шифрования и криптографии, механику хеширования паролей и применение паролей с солью, чтобы понять, почему эксперты по безопасности заботятся об этих темах.
Криптография и шифрование
Чтобы понять, почему были созданы пароли с солью и как они работают, нам сначала нужно изучить важность криптографии и шифрования. Некоторые определения:
Криптография определяется как практика и изучение методов безопасной связи между двумя сторонами в присутствии третьей стороны.
Шифрование — это метод криптографии, при котором сообщение шифруется таким образом, что его могут прочитать только авторизованные стороны, преобразуя открытый текст в неразборчивую серию букв/цифр.
Криптография и шифрование сегодня имеют решающее значение из-за их роли в защите от злоумышленников со всего мира. В связи с тем, что киберпреступность становится самой быстрорастущей преступностью в США и в 2016 году обошлась мировой экономике в более чем 450 миллиардов долларов, использование передовых методов шифрования и криптографии важнее, чем когда-либо.
Если бы вся информация была открытым текстом и не имела шифрования или криптографии вокруг нее, конфиденциальные материалы, такие как информация о паролях, медицинские записи (PII) и даже информация о банковских счетах (PIFI), могли быть украдены и проданы тому, кто предложит самую высокую цену. Один из первых шагов базовой гигиены безопасности — не хранить конфиденциальные данные в открытом виде, особенно пароли. Здесь на помощь приходит хеширование паролей.
Что такое хеширование паролей?
Хеширование пароля определяется как обработка пароля алгоритмом хэширования (bcrypt, SHA и т. д.), чтобы превратить открытый текст в неразборчивую серию цифр и букв. Это важно для базовой гигиены безопасности, потому что в случае нарушения безопасности любые скомпрометированные пароли непонятны злоумышленнику. В результате кража этой информации значительно затруднена.
Ниже приведен пример нескольких слов, прошедших процесс хеширования.
Что такое солевой пароль?
Хеширование паролей — это ключевой шаг к защите ваших пользователей на серверной части, но он не является безошибочным, поскольку хэшируется согласованным образом. Это означает, что он предсказуем и может быть побежден атаками по словарю или атаками по радужным таблицам.
«Привет», например, всегда будет равняться одной и той же комбинации букв и цифр, и поэтому может быть угадан методом перебора. Один из способов защиты от этого — добавление соли или использование соленых паролей.
Соление — это действие по добавлению ряда случайных символов в пароль перед прохождением функции хеширования. Как это работает? Давайте посмотрим:
Как вы можете видеть на изображении выше, мы добавляем ряд случайных чисел и букв к исходному «паролю», чтобы каждый раз получать разные хеш-функции. Таким образом, мы защищаемся от недостатка хэш-функции, каждый раз имея другой хешированный пароль.
Где должны храниться соленые пароли?
С точки зрения того, как это работает в ИТ-инфраструктуре, соли должны храниться в базе данных вместе с паролем пользователя, как показано ниже. Рекомендуется, чтобы соли были случайными и уникальными для каждого входа в систему, чтобы смягчить атаки с использованием радужных таблиц предварительно вычисленных хэшей. Хотя злоумышленник по-прежнему может повторно вычислять хэши общих списков паролей, используя заданную соль для пароля, способ обеспечить дополнительную глубокую защиту — это зашифровать хранилище паролей в состоянии покоя, предпочтительно поддерживаемое HSM или облачной службой управления ключами, такой как AWS KMS. .
Начало пути
Так работают пароли с солью. Но это только верхушка айсберга для обеспечения безопасности ваших клиентских приложений. Понимание этих концепций, связанных с криптографией и шифрованием, — длительный процесс, и при создании приложений, ориентированных на клиентов, создавать эти рабочие процессы непросто.
Как Okta может помочь
Сегодня Okta поддерживает использование паролей с солью, и мы применяем лучшие отраслевые практики для лучшей защиты данных ваших клиентов. Мы поддерживаем стандартизированные алгоритмы хеширования, такие как bcrypt, чтобы лучше защитить пароли ваших клиентов и обеспечить безопасную аутентификацию. Чтобы узнать больше о защите данных ваших клиентов, ознакомьтесь с этими 4 рекомендациями, которые повысят безопасность данных ваших клиентов.
Когда вы храните данные своих клиентов с помощью Okta, мы никогда не допускаем кражу паролей с помощью ограничительных политик администратора. Это предотвращает единую точку уязвимости из-за привилегированного доступа и защищает от захвата учетных записей. Прочтите 3 способа остановить захват аккаунта, чтобы узнать больше о дополнительных шагах, которые вы можете предпринять для обеспечения безопасности аккаунтов ваших клиентов.
Дорога с односторонним движением к усиленной безопасности
Суть аутентификации заключается в том, чтобы предоставить пользователям набор учетных данных, таких как имя пользователя и пароль, и убедиться, что они предоставляют правильные учетные данные всякий раз, когда им требуется доступ к приложению. Следовательно, нам нужен способ сохранить эти учетные данные в нашей базе данных для будущих сравнений. Однако хранение паролей на стороне сервера для аутентификации — сложная задача. Давайте рассмотрим один из механизмов, который делает хранение паролей безопасным и простым: хеширование.
Хранение паролей рискованно и сложно
Простой подход к хранению паролей заключается в создании таблицы в нашей базе данных, которая сопоставляет имя пользователя с паролем. Когда пользователь входит в систему, сервер получает запрос на аутентификацию с полезными данными, содержащими имя пользователя и пароль. Мы ищем имя пользователя в таблице и сравниваем предоставленный пароль с сохраненным паролем. Совпадение дает пользователю доступ к приложению.
Уровень безопасности и отказоустойчивость этой модели зависит от как хранится пароль . Самый простой, но и наименее безопасный формат хранения паролей — открытый текст .
Как объяснил Дэн Корнелл из Denim Group, открытый текст относится к «читаемым данным, переданным или сохраненным в открытом виде », например, незашифрованным. Возможно, вы также видели термины открытый текст и обычный текст . Какая разница? Согласно Корнеллу, открытый текст относится к данным, которые будут служить входными данными для криптографического алгоритма, в то время как открытый текст относится к неформатированному тексту, такому как содержимое простого текстового файла или .текст
. Важно знать разницу между этими терминами по мере продвижения вперед.
Хранение паролей в открытом виде эквивалентно их записи на листе цифровой бумаги. Если злоумышленник проникнет в базу данных и украдет таблицу паролей, он сможет получить доступ к каждой учетной записи пользователя. Эта проблема усугубляется тем фактом, что многие пользователи повторно используют или используют варианты одного пароля, что потенциально позволяет злоумышленнику получить доступ к другим службам, отличным от взломанного. Все это звучит как кошмар безопасности!
Атака могла исходить изнутри организации. Мошенник-разработчик программного обеспечения, имеющий доступ к базе данных, может злоупотребить этим правом доступа, получить учетные данные в открытом виде и получить доступ к любой учетной записи.
Более безопасный способ хранения пароля — преобразовать его в данные, которые нельзя преобразовать обратно в исходный пароль. Этот механизм известен как хеширование . Давайте узнаем больше о теории хеширования, его преимуществах и ограничениях.
«Мы должны защищать учетные записи пользователей как от внутреннего, так и от внешнего несанкционированного доступа. Хранение паролей в открытом виде никогда не должно быть вариантом. Хеширование и добавление соли всегда должны быть частью стратегии управления паролями».
Твитнуть это
О чем хеширование?
По словарному определению, хеширование означает «разбивать что-то на мелкие кусочки», чтобы оно выглядело как «запутанный беспорядок». Это определение тесно связано с тем, что представляет собой хеширование в вычислениях.
В криптографии хэш-функция — это математический алгоритм, который отображает данные любого размера в битовую строку фиксированного размера. Мы можем ссылаться на ввод функции как
- Вычислить хэш легко и практично, но «сложно или невозможно повторно сгенерировать исходный ввод, если известно только значение хеш-функции».
- Трудно создать исходный ввод, который соответствовал бы определенному желаемому выводу.
Таким образом, в отличие от шифрования, хеширование является односторонним механизмом. Данные, которые хешируются, практически не могут быть «не хешированы».
Обычно используемые алгоритмы хеширования включают алгоритмы Message Digest (MDx), такие как MD5, и безопасные алгоритмы хэширования (SHA), такие как SHA-1 и семейство SHA-2, которое включает широко используемый алгоритм SHA-256. . Позже мы узнаем о силе этих алгоритмов и о том, как некоторые из них устарели из-за быстрого прогресса в области вычислений или перестали использоваться из-за уязвимостей в системе безопасности.
В биткойнах целостность и цепочка блоков используют алгоритм SHA-256 в качестве базовой криптографической хеш-функции. Давайте рассмотрим пример хеширования с использованием SHA-256 и Python.
Если вы хотите продолжить, вы можете использовать онлайн-среду Python repl.it IDE для простого запуска сценариев Python.
Python repl.it IDE предоставляет вам редактор кода для ввода кода Python, кнопки для сохранения или запуска скрипта и консоль для визуализации вывода скрипта.
В редакторе кода введите следующую команду, чтобы импортировать метод конструктора хеш-алгоритма SHA-256 из hashlib
module:
from hashlib import sha256
В строке ниже создайте экземпляр класса sha256
:
h = sha256()
Затем используйте метод update() для обновления 900 hash object:
h. update(b'python1990K00L')
Затем используйте метод hexdigest()
, чтобы получить дайджест строки, переданной методу update()
:
hash = h .hexdigest()
Дайджест — это результат хэш-функции.
Наконец, напечатайте переменную hash
, чтобы увидеть значение хеша в консоли:
print(hash)
Полный сценарий выглядит так: ч = ша256 () h.update(b'python1990K00L') хэш = h.hexdigest() print(hash)
Чтобы запустить скрипт, нажмите кнопку «Выполнить» в верхней части экрана. В консоли вы должны увидеть следующий вывод:
d1e8a70b5ccab1dc2f56bbf7e9.9F064A660C08E361A35751B9C483C88943D082
.
d1e8a70b5ccab1dc2f56bbf7e99f064a660c08e361a35751b9c483c88943d082
Попробуйте хэшировать строку python
. Вы получили следующий хэш?
11a4a60b518bf24989d481468076e5d5982884626aed9faeb35b8576fcd223e1
«Понимание блокчейнов и криптовалют, таких как биткойн, становится проще, когда вы понимаете, как работают криптографические хэш-функции».
Tweet This
Используя SHA-256, мы преобразовали ввод случайного размера в битовую строку фиксированного размера. Обратите внимание, что, несмотря на разницу в длине между python1990K00L
и python
, каждый ввод создает хэш одинаковой длины. Почему это?
Используя hexdigest()
, вы создали шестнадцатеричное представление хеш-значения. Для любого ввода каждый вывод дайджеста сообщения в шестнадцатеричном формате содержит 64 шестнадцатеричных цифры. Каждая пара цифр представляет собой байт. Таким образом, дайджест имеет 32 байта. Поскольку каждый байт содержит 8 бит информации, хэш-строка представляет всего 256 бит информации. По этой причине этот алгоритм называется SHA-256, и все его входы имеют выходные данные одинакового размера.
Некоторые хэш-функции широко используются, но их свойства и требования не обеспечивают безопасность. Например, проверка циклическим избыточным кодом (CRC) — это хеш-функция, используемая в сетевых приложениях для обнаружения ошибок, но она не устойчива к предварительным образам, что делает ее непригодной для использования в приложениях безопасности, таких как цифровые подписи.
В этой статье мы собираемся исследовать свойства, которые делают хеш-функцию подходящей для использования в приложениях безопасности. Для начала мы должны знать, что даже если бы мы нашли подробности того, как входные данные криптографической хеш-функции преобразуются в хэш, нам было бы нецелесообразно превращать хэш обратно во входные данные. Почему это?
Криптографические хеш-функции практически необратимы
Хеш-функции ведут себя как однонаправленные функции, используя математические операции, которые чрезвычайно сложно и громоздко отменить, такие как оператор по модулю.
Оператор по модулю дает нам остаток от деления. Например, 5 mod 3
равно 2
, поскольку остаток от 5 / 3
равен 2
при целочисленном делении. Эта операция является детерминированной, поскольку одни и те же входные данные всегда дают один и тот же результат: математически 5 / 3
всегда приводит к 2
. Однако важной характеристикой операции по модулю является то, что мы не можем найти исходные операнды, учитывая результат. В этом смысле хеш-функции необратимы.
Знание того, что результатом операции по модулю является 2
, говорит нам только о том, что x
, деленное на y
, напоминает 2
, но ничего не говорит нам о x
и y
. Существует бесконечное количество значений, которыми можно заменить x
и y
на x mod y
, чтобы получить 2
:
7 mod 5 = 2 9 по модулю 7 = 2 2 по модулю 3 = 2 10 по модулю 8 = 2 ...
При использовании криптографической хэш-функции мы не должны находить предварительное изображение , глядя на хэш . Прообраз — это то, что мы называем значением, которое создает определенный конкретный хэш при использовании в качестве входных данных для хеш-функции — значение открытого текста. Следовательно, криптографическая хеш-функция разработана так, чтобы быть устойчивой к атакам с предварительным изображением; он должен быть устойчивым к прообразу . Таким образом, если злоумышленник знает хэш, вычислительно невозможно найти какие-либо входные данные, которые хешируют этот заданный выход. Именно это свойство делает хеширование одной из основ биткойнов и блокчейнов.
Если вам интересно, как работает хеш-функция, эта статья в Википедии содержит все подробности о том, как работает алгоритм безопасного хэширования 2 (SHA-2).
Небольшое изменение имеет большое значение
Еще одним достоинством защищенной хеш-функции является то, что ее результат нелегко предсказать. Хэш для dontpwnme4
будет сильно отличаться от хэша для dontpwnme5
, даже если изменится только последний символ в строке и обе строки будут соседними в алфавитно отсортированном списке:
Input:
dontpwnme4
Hash (SHA-256):
4420d1918bbcf7686defdf9560bb5087d20076de5f77b7cb4c3b40bf46ec428b
Input:
dontpwnme5
Hash (SHA-256) :
3fc79ff6a81da0b5fc62499d6b6db7dbf1268328052d2da32badef7f82331dd6
Вот скрипт Python, используемый для расчета этих значений, если вам это нужно:
из hashlib импорта sha256 ч = ша256 () h. update(b'') хэш = h.hexdigest() print(hash)
Замените
нужной строкой для хеширования и запустите ее на repl.it.
Это свойство известно как лавинный эффект и имеет желаемый эффект, заключающийся в том, что незначительное изменение входных данных приводит к значительному изменению выходных данных.
Следовательно, мы не можем определить, какой хэш dontpwnme6
будет основан на двух предыдущих хэшах; вывод непоследовательный.
Использование криптографического хеширования для более безопасного хранения паролей
Необратимые математические свойства хеширования делают его феноменальным механизмом для сокрытия паролей в состоянии покоя и в движении. Еще одним важным свойством, которое делает хеш-функции подходящими для хранения паролей, является их детерминированность.
A детерминированная функция – это функция, которая при одних и тех же входных данных всегда производит одинаковые выходные данные. Это жизненно важно для аутентификации, поскольку нам нужна гарантия того, что заданный пароль всегда будет создавать один и тот же хэш; в противном случае было бы невозможно последовательно проверять учетные данные пользователя с помощью этого метода.
Чтобы интегрировать хеширование в рабочий процесс хранения паролей, при создании пользователя вместо сохранения пароля в открытом виде мы хешируем пароль и сохраняем пару имени пользователя и хэша в таблице базы данных. Когда пользователь входит в систему, мы хешируем отправленный пароль и сравниваем его с хешем, связанным с предоставленным именем пользователя. Если хешированный пароль и сохраненный хэш совпадают, у нас есть действующий логин. Важно отметить, что мы никогда не сохраняем пароль в открытом виде в процессе, мы хешируем его, а затем забываем.
В то время как передача пароля должна быть зашифрована, хэш пароля не нужно шифровать в состоянии покоя. При правильной реализации хеширование паролей является криптографически безопасным. Эта реализация будет включать использование соли для преодоления ограничений хеш-функций.
Уникальность является ключевым свойством солей; длина помогает уникальности.
Ограничения хеш-функций
Хеширование кажется довольно надежным. Но если злоумышленник проникнет на сервер и украдет хэши паролей, все, что он сможет увидеть, — это случайно выглядящие данные, которые нельзя преобразовать в открытый текст из-за архитектуры хеш-функций. Злоумышленнику потребуется предоставить входные данные для хэш-функции, чтобы создать хэш, который затем можно использовать для аутентификации, которую можно выполнить в автономном режиме, не поднимая никаких красных флажков на сервере.
Злоумышленник затем может либо украсть пароль в открытом виде у пользователя с помощью современных методов фишинга и спуфинга, либо попробовать атаку методом полного перебора , когда злоумышленник вводит случайные пароли в хеш-функцию до тех пор, пока не будет найден соответствующий хэш.
Атака полным перебором в значительной степени неэффективна, поскольку выполнение хеш-функций может быть настроено на довольно долгое время. Этот «лежачий полицейский» хеширования будет объяснен более подробно позже. Есть ли у злоумышленника другие варианты?
Поскольку хеш-функции являются детерминированными (ввод одной и той же функции всегда приводит к одному и тому же хэшу), если несколько пользователей используют один и тот же пароль, их хеш-код будет идентичным. Если значительное количество людей сопоставляется с одним и тем же хэшем, это может указывать на то, что хэш представляет собой часто используемый пароль, и позволяет злоумышленнику значительно сократить количество паролей, которые можно использовать для взлома методом грубой силы.
Кроме того, через атаку радужного стола , злоумышленник может использовать большую базу данных предварительно вычисленных цепочек хэшей, чтобы найти ввод украденных хэшей паролей. Хеш-цепочка — это одна строка в радужной таблице, хранящаяся как начальное значение хеш-функции и конечное значение, полученное после множества повторных операций с этим начальным значением. Поскольку атака с помощью радужной таблицы должна повторно вычислять многие из этих операций, мы можем смягчить атаку с радужной таблицей, улучшив хеширование с помощью процедуры, которая добавляет уникальные случайные данные к каждому входу в момент их сохранения. Эта практика известна как добавление соли к хешу и получение хэшей паролей с солью .
В случае с солью хэш основывается не только на значении пароля. Ввод состоит из пароля и соли. Радужная таблица построена для набора несоленых хэшей. Если каждый прообраз содержит уникальное значение, которое невозможно угадать, радужная таблица бесполезна. Когда злоумышленник получает соль, радужную таблицу теперь необходимо пересчитать, что в идеале заняло бы очень много времени, что еще больше смягчило бы этот вектор атаки.
"Хитрость заключается в том, чтобы гарантировать, что усилия по "взлому" хеширования превышают ценность, которую преступники получат при этом. Ничто из этого не о том, чтобы быть "неуязвимым"; речь идет о том, чтобы сделать трудность этого не стоящей усилие." - Трой Хант
Нет потребности в скорости
По словам Джеффа Этвуда, «хэши, используемые для обеспечения безопасности, должны быть медленными». Криптографическая хэш-функция, используемая для хеширования паролей, должна быть медленной для вычислений, потому что быстро вычисляемый алгоритм может сделать атаки грубой силы более осуществимыми, особенно с учетом быстро развивающейся мощности современного оборудования. Мы можем добиться этого, сделав вычисление хэша медленным, используя множество внутренних итераций или задействовав память для вычислений.
Медленная криптографическая хеш-функция препятствует этому процессу, но не останавливает его, поскольку скорость хэш-вычисления влияет как на благонамеренных, так и на злонамеренных пользователей. Важно добиться хорошего баланса скорости и удобства использования функций хеширования. Пользователь с благими намерениями не окажет заметного влияния на производительность при попытке единственного действительного входа в систему.
Атаки столкновений не рекомендуют хеш-функции
Поскольку хеш-функции могут принимать входные данные любого размера, но создавать хэши, представляющие собой строки фиксированного размера, множество всех возможных входных данных бесконечно, а множество всех возможных выходных данных конечно. Это позволяет нескольким входным данным сопоставляться с одним и тем же хешем. Следовательно, даже если бы мы могли обратить хэш, мы бы не знали наверняка, что результат был выбранным вводом. Это известно как столкновение, и это нежелательный эффект.
Криптографическая коллизия возникает, когда два уникальных ввода создают один и тот же хэш. Следовательно, атака столкновений — это попытка найти два прообраза, которые производят один и тот же хэш. Злоумышленник может использовать это столкновение, чтобы обмануть системы, которые полагаются на хешированные значения, путем подделки действительного хэша с использованием неверных или вредоносных данных. Следовательно, криптографические хеш-функции также должны быть устойчивы к атаке столкновений, чтобы злоумышленникам было очень трудно найти эти уникальные значения.
Источник: Объявление о первом столкновении SHA1 (Google)
«Поскольку входные данные могут иметь бесконечную длину, а хэши имеют фиксированную длину, коллизии возможны. встречается в часто используемых хеш-функциях».
Tweet This
Для простых алгоритмов хэширования простой поиск в Google позволит нам найти инструменты, которые преобразуют хеш обратно в открытый текст. Алгоритм MD5 сегодня считается опасным, и Google объявила о первой коллизии SHA1 в 2017 году. Оба алгоритма хэширования были признаны небезопасными для использования и объявлены устаревшими Google из-за возникновения криптографических коллизий.
Google рекомендует использовать более надежные алгоритмы хеширования, такие как SHA-256 и SHA-3. Другими часто используемыми на практике вариантами являются bcrypt
, scrypt
и многие другие, которые вы можете найти в этом списке криптографических алгоритмов. Однако, как мы выяснили ранее, одного хеширования недостаточно, и его следует сочетать с солями. Узнайте больше о том, как добавление соли к хешированию — лучший способ хранения паролей.
Резюме
Давайте подытожим то, что мы узнали из этой статьи:
- Основной целью хеширования является создание отпечатка данных для оценки целостности данных.
- Функция хеширования принимает произвольные входные данные и преобразует их в выходные данные фиксированной длины.
- Чтобы квалифицироваться как криптографическая хеш-функция, хэш-функция должна быть устойчивой к прообразу и устойчивой к коллизиям.
- Из-за радужных таблиц одного хеширования недостаточно для защиты паролей для массового использования. Чтобы смягчить этот вектор атаки, хеширование должно интегрировать использование криптографических солей.
- Хэширование пароля используется для проверки целостности вашего пароля, отправленного во время входа в систему, по сравнению с сохраненным хэшем, чтобы ваш фактический пароль никогда не сохранялся.