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


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

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

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

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

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

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

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

4 122

4 ответа:

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

Видимая Сторона Перца

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Лучше

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

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

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

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

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

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

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

TL / DR

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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