В этом посте мы рассмотрим все способы хранения паролей. Мы рассмотрим идеи и недостатки, стоящие за каждым подходом, и выберем наилучший на данный момент способ их хранения.

В каждом случае главный вопрос, на который мы хотим ответить, звучит так: «Что может сделать злоумышленник, если получит доступ к нашей базе данных?»

Подход 1: Храните их в виде открытого текста

Вы, наверное, уже слышали, что это плохая идея. Если кто-то когда-либо получит доступ к нашей базе данных, он получит немедленный доступ ко всем паролям. Мы их совсем не тормозили.

Хотя мы склонны думать о доступе к базе данных как об атаке, он может быть даже не злонамеренным. Возможно, сотруднику нужен доступ только для чтения к БД, и ему также предоставлен доступ к пользовательской таблице. Сохраняя пароли в открытом виде, трудно по-настоящему защитить наших пользователей.

Подход 2: зашифровать их

К сожалению для нас, зашифрованные данные можно расшифровать. Если злоумышленник получает доступ к ключу (что не кажется необоснованным, если он получает доступ к нашей БД), то мы в основном возвращаемся к случаю с открытым текстом. Это, безусловно, лучше, чем случай с открытым текстом, но мы можем добиться большего. Что, если бы мы сохранили пароли в формате, который нельзя отменить?

Подход 3: Хэшируйте их

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

Мы можем только сказать, что кто-то предоставил действительный пароль, хешируя его ввод и проверяя, совпадают ли хэши.

Пока это звучит идеально, однако умный злоумышленник может предварительно вычислить хэши sha256 многих распространенных паролей. Если бы злоумышленник получил доступ к БД и увидел кого-то с хэшем пароля 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8, он мог бы быстро понять, что этот человек выбрал самый распространенный пароль… password

Существуют большие предварительно вычисленные таблицы общих паролей и коротких строк, поэтому нам нужно как-то противодействовать этому.

Подход 4: Солим наши пароли

«Соль» — это случайные данные, которые мы добавляем к нашему паролю.

Несколько важных замечаний:

  • Не существует одной глобальной соли. Каждый пользователь получает свою соль. Глобальная соль по-прежнему позволяет злоумышленнику предварительно вычислять хэши паролей, начиная с этой глобальной соли.
  • Неважно, как вы сочетаете соль и пароль. В этом случае мы просто добавили его.

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

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

Это делается путем вычисления хэшей для определенной соли пользователей с набором данных общих паролей. Хороший пароль по-прежнему будет очень трудно взломать, но злоумышленник может использовать соли для относительно быстрого поиска людей со слабыми паролями.

Что, если бы мы могли намеренно сделать наш алгоритм хеширования более трудным для вычисления?

Подход 5: Используйте современный алгоритм хеширования паролей

Согласно OWASP, Argon2id, bcrypt, scrypt и PBKDF2 применимы в разных сценариях.

Основное отличие современных алгоритмов хеширования паролей от чего-то вроде sha256 заключается в том, что их производительность можно настраивать.

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

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

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

Как настроить алгоритм хеширования пароля?

Эти алгоритмы великолепны, но у них есть некоторые параметры, которые необходимо установить. Хорошим местом для начала является Руководство OWASP по хранению паролей, в котором есть рекомендации по параметрам.

Эшелонированная защита

Хотя мы рассмотрели передовые методы фактического хранения пароля, для дополнительной защиты пользователей вам также следует рассмотреть такие методы, как обнаружение взлома пароля, чтобы пользователи не могли использовать легко угадываемые пароли.

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

Выводы

  • Всегда используйте современный алгоритм хэширования и следуйте Руководству OWASP, чтобы настроить его.
  • Никогда не храните пароли в обратном формате
  • В случае утечки данных хороший пароль — лучшая защита вашего пользователя. Такие методы, как обнаружение взлома пароля, также могут помочь смягчить некоторые из этих проблем.