Веб-приложение - Сохранение пароля

Я что-нибудь пропустил? Есть ли какие-то дополнительные действия по хранению паролей к БД?

Сохранение пароля:
Проведя как можно больше исследований по этому вопросу, я пришел к выводу, что лучший способ хранить пароли пользователей в БД веб-приложений (в моем случае MySQL + PHP) выглядит следующим образом:

  • Назначьте статическую соль по всему сайту. (16 случайных символов, включая 0-9, a-z, A-Z, [] / * - ')
  • Назначьте случайную соль для каждого пользователя (хранящуюся в БД).
  • Сохраните результат hash_function ($ userPassword + $ sitewideSalt + $ randomSalt)
  • Сохраните $ randomSalt вместе с полученным хешем.
  • Используйте регулируемое хеширование рабочей нагрузки bcrypt

  • Атака №1. Злоумышленник выгружает базу данных с помощью SQL-инъекции.
    Результаты нашей хэш-функции и случайной соли для каждого пользователя в базе данных.

    После дампа злоумышленник мог получить $ userPassword и $ randomSalt, просмотрев свою учетную запись. Затем, угадав хэш-функцию, такую ​​как md5, он мог начать радужную атаку на $ sitewideSalt. Но это может занять до 1,41 миллиона столетий [1].

    Использование этого типа безопасности не позволяет дамп БД поставить под угрозу сохраненные пароли. Пользователь все равно должен найти $ sitewideSalt другим способом.

  • Атака №2: Злоумышленник находит вектор включения локального файла (LFI).
    Злоумышленник может получить необработанный код для нашего веб-приложения.

    После использования веб-приложения с помощью возможного LFI или RFI [2] злоумышленник считывает исходный код нашего веб-приложения и получает наш простой алгоритм и сохраненную
    $ sitewideSalt.


Куда дальше?
Теперь у злоумышленника есть обе возможности, и он может начать поиск реальных паролей. За исключением того, что он должен создать по одной радужной таблице для каждого пользователя, поскольку у каждого пользователя есть своя соль, специфичная для случайного пользователя ($ randomSalt).

«Современный сервер может вычислять хэш MD5 размером около 330 МБ каждую секунду. Если у ваших пользователей есть пароли в нижнем регистре, буквенно-цифровые и длиной 6 символов, вы можете попробовать каждый возможный пароль такого размера примерно за 40 секунд».
«... CUDA, вы можете собрать свой собственный небольшой суперкомпьютерный кластер, который позволит вам пробовать около 700 000 000 паролей в секунду ...» [3]

Что нам нужно сделать сейчас, так это расширить функцию хеширования, используя трудоемкий алгоритм, такой как bcrypt. Коэффициент загрузки bcrypt может быть на 5-6 порядков больше, чем у более простых хеш-функций. На взлом одного пароля могут уйти годы, а не минуты. И в качестве бонуса bcrypt уже генерирует случайную соль для каждого хэша и сохраняет ее в результирующем хэше.

  1. http://www.grc.com/haystack.htm
  2. http://www.wildcardsecurity.com/security101/index.php?title=Local_File_Inclusion

person davidg    schedule 24.06.2011    source источник


Ответы (2)


Хорошо сделано! Для меня это выглядит очень полным.

Единственные предложения, которые у меня были бы:

Поверните служебную соль.

Разработайте метод периодической ротации поваренной соли и регулярно выполняйте ее.

Например, после создания новой служебной соли используйте ее для всех новых учетных записей и любых изменений пароля. Когда существующий пользователь пытается войти в систему, аутентифицируйте его с помощью старой служебной соли. В случае успеха обновите их хэш с помощью новой служебной соли (и, возможно, новой пользовательской соли). Для пользователей, которые не входят в систему в течение «некоторого времени», случайным образом сгенерируйте новый пароль от их имени. Это будет поддерживать безопасность пользователей, покинувших ваш сайт, вынуждая тех, кто возвращается, использовать средства для сброса пароля. («некоторое время» = любой период, который вам удобен).

Не усложняйте код служебной соли.

Не позволяйте атаке LFI поставить под угрозу вашу служебную соль. Загрузите служебную соль в ваше приложение при запуске и сохраните ее в памяти. Чтобы скомпрометировать служебную соль, злоумышленнику потребуется выполнить код для чтения соли из памяти. Если злоумышленник может это сделать, вы в любом случае неплохо промочили. знак равно

Не используйте повторно пользовательскую соль.

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

(Пометить это как вики сообщества, если у других появятся дополнительные идеи).

person Community    schedule 26.06.2011
comment
я немного смущен. как работает логика служебной соли для аутентификации? Я предполагаю, что храню служебную соль в mysql, а затем при входе в систему я добавляю ее к хешу пользователя и сохраняю хеш и проверяю, равны ли они. но разве это не то же самое, что не иметь служебной соли? поскольку если и пользовательский хеш, и хэш хранилища совпадают, то добавление служебной соли также будет совпадать. - person ; 25.07.2012
comment
Зачем нужно регулярно переворачивать соль? - person sam; 16.01.2014

Использование BCrypt для обработки паролей - единственный шаг, или, скорее, он включает в себя следующее:

  1. Возьмите пароль, передайте его библиотеке BCrypt.
  2. Сохраните полученный хеш.
  3. Сравните пароль с хешем.

Вы также забыли эту ссылку: http://codahale.com/how-to-safely-store-a-password/, на который вы ссылаетесь в цитате.

person krainboltgreene    schedule 24.06.2011