Рекомендации: солить и перчить пароли?
Я наткнулся на дискуссию, в которой я узнал, что на самом деле я не солю пароли, а перчу их, и с тех пор я начал делать и то и другое с помощью функции, такой как:
hash_function($salt.hash_function($pepper.$password)) [multiple iterations]
Игнорируя выбранный алгоритм хэша (я хочу, чтобы это было обсуждение солей и перцев, а не конкретных алгоритмов, но я использую безопасный), это безопасный вариант или я должен делать что-то другое? Для тех, кто не знаком с терминами:
А соль - это случайно генерируемое значение обычно хранится вместе со строкой в базе данных, предназначенной для того, чтобы сделать невозможным использование хэш-таблиц для взлома паролей. Поскольку каждый пароль имеет свою собственную соль, все они должны быть грубо обработаны индивидуально, чтобы взломать их; однако, поскольку соль хранится в базе данных с хэшем пароля, компрометация базы данных означает потерю обоих.
A pepper - это статическое значение для всего сайта, хранящееся отдельно от базы данных (обычно жестко закодированное в исходный код приложения), который должен быть секретным. Он используется для того, чтобы компрометация базы данных не приводила к тому, что вся таблица паролей приложения была бы грубой силой.
Есть ли что-то, что я упускаю, и является ли соление и перчение моих паролей лучшим вариантом для защиты безопасности моего пользователя? Есть ли какой-либо потенциальный недостаток безопасности, чтобы сделать это таким образом?
Примечание: предположим для целей обсуждения, что приложение и база данных хранятся на отдельные машины, не обмениваются паролями и т. д. таким образом, нарушение работы сервера баз данных не означает автоматического нарушения работы сервера приложений.
4 ответов:
Хорошо. Поскольку мне нужно написать об этом над и над, я сделаю последний канонический ответ только на Пеппер.
Очевидная Положительная Сторона Перцев
Кажется совершенно очевидным, что peppers должны сделать хэш-функции более безопасными. Я имею в виду, если злоумышленник получает только вашу базу данных, то ваши пароли пользователей должны быть защищены, верно? Кажется логичным, не так ли?
Вот почему так много людей считают, что перец-это хорошая идея. Это "имеет смысл".В Реальность Перцев
В области безопасности и криптографии "иметь смысл" недостаточно. Что-то должно быть доказуемым и иметь смысл, чтобы это считалось безопасным. Кроме того, он должен быть осуществим в ремонтопригодном виде. Самая безопасная система, которая не может быть поддержана, считается небезопасной (потому что если какая-либо часть этой безопасности сломается, вся система развалится).
А перцы не подходят ни под доказуемое, ни под ремонтопригодное модели...
Теоретические Проблемы С Перцем
Теперь, когда мы подготовили почву, давайте посмотрим, что не так с перцем.
Скармливать один гашиш другому может быть опасно.
В вашем примере Вы делаете
Мы знаем из прошлого опыта, что "просто подача" одного хэш-результата в другую хэш-функцию может снизить общую безопасность. Причина в том, что обе хэш-функции могут стать объектом атаки.hash_function($salt . hash_function($pepper . $password)).Вот почему алгоритмы, подобные PBKDF2 , используют специальные операции для их объединения (в этом случае hmac).
Дело в том, что, хотя это не так уж и важно, это также не тривиальная вещь, которую можно просто бросить. Криптосистемы предназначены для того, чтобы избегать случаев "должен работать", а вместо этого сосредоточиться на случаях "предназначен для работы". Хотя это может показаться чисто теоретическим, на самом деле это не так. Например, Bcrypt не может принимать произвольные пароли . Таким образом, передачаbcrypt(hash(pw), salt)действительно может привести к гораздо более слабому хэшу чемbcrypt(pw, salt), еслиhash()возвращает двоичную строку.Работа Против Дизайна
Способ, которым были разработаны bcrypt (и другие алгоритмы хэширования паролей), заключается в работе с солью. Понятие перца никогда не вводилось. Это может показаться тривиальным, но это не так. Причина в том, что соль не является секретом. Это просто значение, которое может быть известно злоумышленнику. С другой стороны, перец по определению является криптографическим секретом.
Ток алгоритмы хэширования паролей (bcrypt, pbkdf2 и т. д.) предназначены только для одного секретного значения (пароля). Добавление еще одного секрета в алгоритм вообще не изучалось.
Это не значит, что это не безопасно. Это значит, что мы не знаем, безопасно ли это. И общая рекомендация в отношении безопасности и криптографии заключается в том, что если мы не знаем, то это не так.
Таким образом, пока алгоритмы не разработаны и не проверены криптографами для использования с секретными значениями (перцами), текущие алгоритмы не следует использовать их вместе.
Сложность-Враг Безопасности
Хотите верьте, хотите нет, но сложность-враг безопасности. Создание алгоритма, который выглядит сложным, может быть безопасным, а может и нет. Но вероятность того, что это не безопасно, весьма велика.Значительные Проблемы С Перцем
Это не ремонтопригодно
Ваша реализация перца исключает возможность поверните ключ перцем. Поскольку перец используется на входе в одностороннюю функцию, вы никогда не сможете изменить перец в течение всего срока действия значения. Это означает, что вам нужно было бы придумать несколько шатких хаков, чтобы заставить его поддерживать вращение клавиш.
Эточрезвычайно важно, поскольку это требуется всякий раз, когда вы храните криптографические секреты. Отсутствие механизма поворота ключей (периодически и после нарушения) является огромной уязвимостью системы безопасности.
И ваш нынешний перец подход потребует, чтобы каждый пользователь либо полностью аннулировал свой пароль при ротации, либо ждал, пока его следующий логин не будет вращаться (что может быть никогда)...
Что в принципе делает ваш подход немедленным отказом.
Он Требует, Чтобы Вы Свернули Свой Собственный Крипто
Поскольку ни один из существующих алгоритмов не поддерживает концепцию перца, требуется либо создавать алгоритмы, либо изобретать новые для поддержки перца. А если вы не можете сразу же смотрите, почему это действительно плохо:Любой человек, от самого невежественного любителя до лучшего криптографа, может создать алгоритм, который он сам не сможет взломать.Никогда не бросайте свою собственную криптографию...
Лучший Способ
Таким образом, из всех проблем, описанных выше, есть два способа справиться с ситуацией.
Просто Используйте Алгоритмы, Как Они Существуют
Если вы используете bcrypt или scrypt правильно (с высокой стоимостью), все пароли, кроме самых слабых словарей, должны быть статистически безопасными. Текущий рекорд по хешированию bcrypt при стоимости 5 составляет 71 тыс. хэшей в секунду. С такой скоростью даже случайный пароль из 6 символов будет взламываться годами. И учитывая, что моя минимальная рекомендуемая стоимость составляет 10, это уменьшает хэши в секунду в 32 раза. Таким образом, мы будем говорить только о 2200 хэшах в секунду. С такой скоростью даже какой-нибудь словарь фразы или модификации могут быть безопасными.
Кроме того, мы должны проверять наличие этих слабых классов паролей у двери и не позволять им входить. По мере того как взламывание паролей становится все более продвинутым, то же самое должно происходить и с требованиями к качеству паролей. Это все еще статистическая игра, но с правильной техникой хранения и надежными паролями каждый должен быть практически в полной безопасности...
Зашифруйте Выходной Хэш Перед Хранением
Существует в сфере безопасности алгоритм, предназначенный для обработки всего, что мы сказали выше. Это блочный шифр. Это хорошо, потому что это обратимо, так что мы можем вращать клавиши (ура! ремонтопригодность!). Это хорошо, потому что он используется так, как задумано. Это хорошо, потому что он не дает пользователю никакой информации.
Давайте еще раз взглянем на эту линию. Предположим, что злоумышленник знает ваш алгоритм (который необходим для обеспечения безопасности, иначе это безопасность через неизвестность). С традиционным подходом перца, атакующий может создать пароль стража, и так как он знает соль и выход, он может грубо заставить перец. Ладно, это маловероятно, но вполне возможно. С шифром злоумышленник ничего не получит. А поскольку соль рандомизирована, пароль стража даже не поможет ему / ей. Поэтому лучшее, что им остается, - это атаковать зашифрованную форму. Это означает, что сначала они должны атаковать ваш зашифрованный хэш, чтобы восстановить ключ шифрования, а затем атаковать хэши. Но есть много исследований в области атака шифров, поэтому мы хотим полагаться на это.TL / DR
Не используйте перец. Существует множество проблем с ними, и есть два лучших способа: не использовать какой-либо серверный секрет (да, это нормально) и шифровать выходной хэш с помощью блочного шифра перед хранением.
Кулак мы должны говорить о точном преимуществе перца :
Pepper может защитить слабые пароли от атаки по словарю, в особом случае, когда злоумышленник имеет доступ на чтение к базе данных (содержащей хэши), но не имеет доступа к исходному коду с помощью pepper.
Типичным сценарием была бы SQL-инъекция, выброшенные резервные копии, выброшенные серверы... Такие ситуации не так уж редки, как кажется, и зачастую не находятся под вашим контролем (сервер-хостинг). Если вы используете...
- уникальная соль на пароль
- медленный алгоритм хэширования, такой как BCrypt
...надежные пароли хорошо защищены. В таких условиях почти невозможно перебрать надежный пароль, даже если соль известна. Проблема заключается в слабых паролях, которые являются частью словаря грубой силы или являются их производными. Атака по словарю покажет их очень быстро, потому что вы проверяете только самые распространенные пароли.
Второй вопрос: Как применять перец?
Часто рекомендуемый способ применения перца-это объединить пароль и перец перед передачей его в хэш-функцию:
$pepperedPassword = hash_hmac('sha512', $password, $pepper); $passwordHash = bcrypt($pepperedPassword);Хотя есть и другой, еще лучший способ:
$passwordHash = bcrypt($password); $encryptedHash = encrypt($passwordHash, $serverSideKey);Это не только позволяет добавить Секрет на стороне сервера, но и позволяет обменять $serverSideKey, если это необходимо. Этот метод требует немного больше работы, но если код уже существует (библиотека) нет причин не использовать его.
Смысл соли и перца в том, чтобы увеличить стоимость предварительно вычисленного поиска пароля, называемого радужной таблицей.
В общем случае трудно найти коллизию для одного хэша (предполагая, что хэш безопасен). Однако с короткими хэшами можно использовать компьютер для создания всех возможных хэшей в поиске на жестком диске. Это называется Радужный стол. Если вы создадите радужную таблицу, вы можете выйти в мир и быстро найти подходящие пароли для любого из них. (несоленая нерафинированная) гашиш.
Смысл перца в том, чтобы сделать радужную таблицу, необходимую для взлома вашего списка паролей, уникальной. Таким образом, тратя больше времени на атакующего, чтобы построить радужную таблицу.
Смысл соли, однако, состоит в том, чтобы сделать радужную таблицу для каждого пользователя уникальной для пользователя, что еще больше увеличивает сложность атаки.
На самом деле смысл компьютерной безопасности почти никогда не заключается в том, чтобы сделать ее (математически) невозможной, просто математически и физически непрактично (например, в защищенных системах для вычисления пароля одного пользователя потребовалась бы вся энтропия Вселенной (и даже больше)).
Не может рассматривать хранение жестко закодированного значения в исходном коде как имеющее какое-либо отношение к безопасности. Это безопасность через неясность.
Если хакер заполучит вашу базу данных, он сможет начать грубое принуждение ваших паролей пользователей. Этому хакеру не потребуется много времени, чтобы идентифицировать ваш перец, если ему удастся взломать несколько паролей.
Comments