Лучшие практики: солить и перчить пароли?

я наткнулся на дискуссию, в которой я узнал, что то, что я делал, на самом деле не солить пароли, а перчить их, и с тех пор я начал делать оба с функцией, как:

hash_function($salt.hash_function($pepper.$password)) [multiple iterations]

игнорируя выбранный алгоритм хэша (я хочу, чтобы это было обсуждение солей и перцев, а не конкретных алгоритмов, но я использую безопасный), это безопасный вариант или я должен делать что-то другое? Для тех, кто не знаком с терминами:

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

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

есть ли что-то, чего мне не хватает, и солить и перчить мои пароли-лучший вариант для защиты безопасности моего пользователя? Есть ли какой-либо потенциальный недостаток безопасности, чтобы сделать это таким образом?

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

4 ответов


Ok. Видя, как мне нужно написать об этом над и над, Я сделаю последний канонический ответ только на перец.

Очевидный Плюс Перца

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

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

Реальность Перцев

в области безопасности и криптографии "иметь смысл" недостаточно. Что-то должно быть доказуемым!--19-->и имеет смысл для того, чтобы считаться безопасным. Кроме того, он должен быть реализован в ремонтопригодном виде. Самая безопасная система, которую нельзя поддерживать, считается небезопасной (потому что если какая-либо часть этой безопасности ломается, вся система разваливается).

и перцы посадка ни доказуемые, ни ремонтопригодные модели...

Теоретические Проблемы С Перец

теперь, когда мы установили сцену, давайте посмотрим, что не так с перцем.

  • скармливание одного хэша другому может быть опасным.

    в вашем примере, Вы делаете hash_function($salt . hash_function($pepper . $password)).

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

    вот почему алгоритмы, такие как PBKDF2 с используйте специальные операции для их объединения (в этом случае hmac).

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

    хотя это может показаться чисто теоретическим, на самом деле он не. Для пример,Bcrypt не может принимать произвольные пароли. Так мимоходом bcrypt(hash(pw), salt) действительно может привести к гораздо более слабому хэшу, чем bcrypt(pw, salt) Если hash() возвращает двоичную строку.

  • Работает Против Дизайна!--20-->

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

    текущие алгоритмы хэширования паролей (bcrypt, pbkdf2 и т. д.) предназначены только для одного секретного значения (пароль). Добавление еще одного секрета в алгоритм вообще не изучалось.

    это не значит, что это не безопасно. Это значит, что мы не знаем, безопасно ли это. И общая рекомендация с безопасностью и криптография заключается в том, что если мы не знаем, то это не так.--9-->

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

  • Сложность-Враг Безопасности!--20-->

    Веришь или нет, Сложность-Враг Безопасности!--6-->. Создание алгоритма, который выглядит сложным, может быть безопасным, а может и нет. Но шансы есть. важно, что это небезопасно.

Значительные Проблемы С Перцем

  • это не ремонтопригодно

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

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

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

    которая в основном делает ваш приблизьтесь к немедленному отказу.

  • Это Требует От Вас, Чтобы Свернуть Свой Собственный Crypto

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

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

    никогда свернуть свой собственный крипто...

Лучше

Итак, из всех проблем описанных выше, существует два способа справиться с ситуацией.

  • Просто Используйте Алгоритмы, Как Они Существуют

    если вы используете bcrypt или scrypt правильно (с высокой стоимостью), все, кроме самые слабые пароли словаря должны быть статистически безопасными. Текущая запись для хэширования bcrypt по цене 5 составляет 71k хэшей в секунду. При такой скорости даже случайный пароль из 6 символов займет годы, чтобы взломать. И учитывая, что моя минимальная рекомендуемая стоимость составляет 10, это уменьшает хэши в секунду в 32 раза. Таким образом, мы будем говорить только о 2200 хэшах в секунду. В таком случае, даже словарь фраз или modificaitons может быть безопасным.

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

  • Шифрование Выходного Хэша Перед Хранением

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

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

TL / DR

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


во-первых, мы должны говорить о точное преимущество перец:

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

типичным сценарием будет SQL-инъекция, выброшенные резервные копии, выброшенные серверы... Эти ситуации не так редки, как кажется, и часто не под вашим контролем (сервер-хостинг). Если вы используете...

  • уникальная соль на пароль
  • медленный алгоритм хэширования, такой как BCrypt

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

второй вопрос:как применять перец ?

часто рекомендуемый способ применения перца-это объединить пароль и перец перед передачей его в хэш-функцию:

$pepperedPassword = hash_hmac('sha512', $password, $pepper);
$passwordHash = bcrypt($pepperedPassword);

есть еще один еще лучший способ, хотя:

$passwordHash = bcrypt($password);
$encryptedHash = encrypt($passwordHash, $serverSideKey);

это не только позволяет добавить Секрет на стороне сервера, но и позволяет обменять $serverSideKey, если это необходимо. Этот метод включает в себя немного больше работы, но если код когда-то существует (библиотека), нет причин не использовать его.


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

В общем, попытка найти столкновение для одного хэша трудна (предполагая, что хэш безопасен). Однако с короткими хэшами можно использовать компьютер для создания всех возможных хэшей в поиске на жестком диске. Это называется радужным столом. Если вы создадите радужную таблицу, вы сможете выйти в мир и быстро найти подходящие пароли для любых (несоленого unpeppered) хэш.

точка перца сделать радужную таблицу нужно взломать свой пароль уникальным. Таким образом, тратить больше времени на злоумышленника, чтобы построить радужную таблицу.

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

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


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

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