Безопасный хэш и соль для паролей PHP


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

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

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

  1. Механизм хеширования должен быть доступен в PHP
  2. Это должно быть безопасно
  3. Он может использовать соль (в этом случае все соли одинаково хороши? Есть ли какой-нибудь способ получить хорошие соли?)

Кроме того, следует ли хранить два поля в базе данных (одно с использованием MD5, а другое один, использующий SHA, например)? Сделает ли это его безопаснее или небезопаснее?

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

Связанные вопросы, которые не совсем охватывают мой вопрос:

В чем разница между SHA и MD5 в PHP
Простое Шифрование Пароля
Безопасные методы хранения ключей, паролей для asp.net
Как бы вы реализовали соленые пароли в Tomcat 5.5

Author: Community, 2008-12-31

14 answers

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Этот ответ был написан в 2008 году.

С тех пор PHP дал нам password_hash и password_verify и с момента их введения они являются рекомендуемым методом хеширования и проверки паролей.

Хотя теория ответа все еще хороша для чтения.

TL;ДР

Нельзя

  • Не ограничивайте количество символов, которые пользователи могут вводить в качестве паролей. Только идиоты делают это.
  • Не ограничивайте длина пароля. Если вашим пользователям нужно предложение с суперкалифрагилистическим выражением замечательно, не запрещайте им его использовать.
  • Никогда не храните пароль пользователя в виде обычного текста.
  • Никогда не отправляйте пароль по электронной почте своему пользователю , за исключением случаев, когда он потерял свой пароль, а вы отправили временный.
  • Никогда, никогда не регистрируйте пароли каким-либо образом.
  • Никогда не хэшируйте пароли с помощью SHA1 или MD5 или даже SHA256! Современные крекеры могут превышать 60 и 180 миллиардов хэшей в секунду (соответственно).
  • Не смешивайте bcrypt и с необработанным выводом hash(), либо используйте шестнадцатеричный вывод, либо base64_encode. (Это относится к любому входу, в котором может содержаться мошенник \0, что может серьезно ослабить безопасность.)

Dos

  • Используйте scrypt, когда можете; bcrypt, если не можете.
  • Используйте PBKDF2, если вы не можете использовать ни bcrypt, ни scrypt, с хэшами SHA2.
  • Сбросить пароли всех пользователей, когда база данных скомпрометирована.
  • Реализуйте разумную минимальную длину 8-10 символов, а также требуйте, по крайней мере, 1 заглавную букву, 1 строчную букву, число и символ. Это улучшит энтропию пароля, что, в свою очередь, затруднит его взлом. (См. Раздел "Что делает пароль хорошим?" раздел для некоторых дебатов.)

Зачем вообще хэшировать пароли?

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

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

Иеремия Гроссман, технический директор Whitehat Security, заявил в своем блоге после недавнего восстановления пароля, которое потребовало взлома его защиты паролем методом грубой силы:

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

(Курсив мой.)

Что вообще делает хорошим паролем?

Энтропия. (Не то чтобы я полностью разделял точку зрения Рэндалла.)

Короче говоря, энтропия - это то, насколько сильно изменяется пароль. Когда пароль состоит только из строчных латинских букв, это только 26 символов. Это не такая уж большая разница. Буквенно-цифровые пароли лучше, с 36 символами. Но разрешение верхнего и нижнего регистра с символами составляет примерно 96 символов. Это намного лучше, чем просто письма. Одна из проблем заключается в том, что для того, чтобы наши пароли запоминались, мы вставляем шаблоны, что уменьшает энтропию. Упс!

Энтропия пароля легко аппроксимируется . Использование полного набора символов ascii (примерно 96 типизируемых символов) дает энтропию 6,6 на символ, что при 8 символов для пароля все еще слишком мало (52,679 бит энтропии) для обеспечения безопасности в будущем. Но хорошая новость заключается в том, что более длинные пароли и пароли с символами юникода действительно увеличивают энтропию пароля и затрудняют его взлом.

На сайте Crypto StackExchange более подробно обсуждается энтропия паролей. Хороший поиск в Google также даст много результатов.

В комментариях я поговорил с @popnoodles, который указал, что принудительное исполнение политика паролей длиной X с X большим количеством букв, цифр, символов и т.д. Может фактически уменьшить энтропию, сделав схему паролей более предсказуемой. Я действительно согласен. Случайность, настолько по-настоящему случайная, насколько это возможно, всегда является самым безопасным, но наименее запоминающимся решением.

Насколько я могу судить, создание лучшего в мире пароля - это уловка-22. Либо он не запоминающийся, слишком предсказуемый, слишком короткий, слишком много символов юникода (трудно вводить на устройстве Windows/Mobile), слишком длинный и т.д. Без пароля действительно достаточно хорош для наших целей, поэтому мы должны защищать их, как если бы они были в Форт-Ноксе.

Лучшие практики

Bcrypt и scrypt являются текущими лучшими практиками. Scrypt со временем будет лучше, чем bcrypt, но он еще не был принят в качестве стандарта Linux/Unix или веб-серверами, и еще не были опубликованы подробные обзоры его алгоритма. Но все же будущее алгоритма выглядит многообещающим. Если вы работаете с Ruby, есть зашифруйте драгоценный камень, который поможет вам, и Node.js теперь имеет свой собственный пакет scrypt. Вы можете использовать Scrypt в PHP либо с помощью расширения Scrypt, либо с расширением Libsodium (оба доступны в PECL).

Я настоятельно рекомендую прочитать документацию по функции шифрования , если вы хотите понять, как использовать bcrypt, или найти себе хороший оболочка или используйте что-то вроде PHPASS для более унаследованная реализация. Я рекомендую минимум 12 раундов bcrypt, если не от 15 до 18.

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

Средние практики

Я почти не могу представить себе эту ситуацию больше. PHPASS поддерживает PHP с 3.0.18 по 5.3, поэтому он может использоваться практически во всех мыслимых установках - и его следует использовать, если вы не знаете наверняка, что ваша среда поддерживает bcrypt.

Но предположим, что вы вообще не можете использовать bcrypt или PHPASS. Что тогда?

Попробуйте реализовать PDKBF2 с максимальным количеством раундов , которое может выдержать ваша среда/приложение/восприятие пользователя. Самое низкое число, которое я бы рекомендовал, - 2500 патронов. Кроме того, обязательно используйте hash_hmac(), если это доступен для усложнения воспроизведения операции.

Будущая практика

В PHP 5.5 входит полная библиотека защиты паролем, которая устраняет любые трудности при работе с bcrypt. В то время как большинство из нас застряли с PHP 5.2 и 5.3 в большинстве распространенных сред, особенно на общих хостах, @ircmaxell создал уровень совместимости для будущего API, который обратно совместим с PHP 5.3.7.

Краткое описание криптографии и отказ от ответственности

В вычислительная мощность, необходимая для фактического взлома хэшированного пароля, не существует. Единственный способ для компьютеров "взломать" пароль - это воссоздать его и смоделировать алгоритм хеширования, используемый для его защиты. Скорость хэша линейно связана с его способностью к принудительному использованию. Что еще хуже, большинство алгоритмов хэширования могут быть легко распараллелены, чтобы работать еще быстрее. Вот почему так важны дорогостоящие схемы, такие как bcrypt и scrypt.

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

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

 903
Author: Robert K, 2017-05-23 12:10:41

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

  • PHP 5.5 или выше: password_hash() является хорошим качеством и частью ядра PHP.
  • Более старые версии PHP: библиотека openwall phpass намного лучше, чем большинство пользовательских кодов, используемых в WordPress, Drupal и т.д.

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

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

Например, вы можете взломать все 8-символьные пароли Windows за 6 часы с использованием 25 графических процессоров, установленных на 5 настольных ПК. Это грубое принуждение, т.е. перечисление и проверка каждого 8-символьного пароля Windows, включая специальные символы, и не является атакой по словарю. Это было в 2012 году, с 2018 года вы могли использовать меньше графических процессоров или быстрее взламывать 25 графических процессоров.

Также существует множество атак с использованием радужных таблиц на пароли Windows, которые выполняются на обычных процессорах и очень быстры. Все это потому, что Windows все еще не солит и не растяните свои пароли, даже в Windows 10 - не совершайте ту же ошибку, что и Microsoft!

См. также:

  • отличный ответ с более подробной информацией о том, почему password_hash() или phpass являются лучшим способом.
  • хорошая статья в блоге, содержащая рекомендуемые "факторы работы" (количество итераций) для основных алгоритмов, включая bcrypt, scrypt и PBKDF2.
 120
Author: RichVel, 2018-03-20 09:48:43

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

 40
Author: Tom Haigh, 2013-01-17 14:22:05

Начиная с PHP 5.5, PHP имеет простые, безопасные функции для хеширования и проверки паролей, password_hash() и password_verify()

$password = 'anna';
$hash = password_hash($password, PASSWORD_DEFAULT);
$expensiveHash = password_hash($password, PASSWORD_DEFAULT, array('cost' => 20));

password_verify('anna', $hash); //Returns true
password_verify('anna', $expensiveHash); //Also returns true
password_verify('elsa', $hash); //Returns false

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

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

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

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

 31
Author: AlliterativeAlice, 2015-08-25 19:08:11

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

Более подробное объяснение доступно по адресу - http://www.pivotalsecurity.com/blog/password-hashing-salt-should-it-be-random/

Недавно у меня была дискуссия о том, являются ли хэши паролей, засоленные случайными битами, более безопасными, чем хэши, засоленные предполагаемыми или известными солями. Давайте посмотрим: Если система, хранящая пароль, скомпрометирована так же, как и система, в которой хранится случайная соль, злоумышленник будет иметь доступ как к хэшу, так и к соли, поэтому случайна соль или нет, не имеет значения. Злоумышленник может сгенерировать предварительно вычисленные радужные таблицы, чтобы взломать хэш. Здесь начинается интересная часть - генерировать предварительно вычисленные таблицы не так уж и тривиально. Давайте рассмотрим пример модели безопасности WPA. Ваш пароль WPA на самом деле никогда не отправляется на Точку беспроводного доступа. Вместо, он хэшируется с вашим SSID ( сетевое имя - например, Linksys, Dlink и т. Д.). Очень хорошее объяснение того, как это работает, находится здесь. Чтобы получить пароль из хэша, вам нужно будет знать пароль, а также соль (сетевое имя). Церковь Wi-Fi уже имеет предварительно вычисленные хэш-таблицы, в которых содержится 1000 лучших SSID и около 1 миллиона паролей. Размер всех таблиц составляет около 40 ГБ. Как вы можете прочитать на их сайте, кто-то использовал 15 массивов FGPA в течение 3 дней для создания этих таблиц. Предполагая, что жертва использует SSID в качестве "a387csf3" и пароль "123456", будут ли они взломаны этими таблицами? Нет!.. это невозможно. Даже если пароль слабый, в таблицах нет хэшей для SSID a387csf3. В этом и заключается прелесть наличия случайной соли. Это отпугнет взломщиков, которые процветают на предварительно вычисленных таблицах. Может ли это остановить решительного хакера? Наверное, нет. Но использование случайных солей обеспечивает дополнительный уровень защиты. Пока мы обсуждаем эту тему, давайте обсудим дополнительные преимущества хранения случайных соли по отдельной системе. Сценарий № 1: Хэши паролей хранятся в системе X, а значения соли, используемые для хэширования, хранятся в системе Y. Эти значения соли являются угадываемыми или известными (например, имя пользователя) Сценарий № 2 : Хэши паролей хранятся в системе X, а значения соли, используемые для хэширования, хранятся в системе Y. Эти значения соли являются случайными. В случае , если система X была скомпрометирована, как вы можете догадаться, есть огромное преимущество использования случайной соли в отдельной системе (Сценарий № 2). Злоумышленнику нужно будет угадать значения сложения, чтобы иметь возможность взломать хэши. Если используется 32-битная соль, 2^32 = 4 294 967 296 (около 4,2 миллиард) итераций может потребоваться для каждого угаданного пароля.

 30
Author: Gaurav Kumar, 2012-06-27 16:10:17

Я просто хочу отметить, что PHP 5.5 включает в себя API хеширования паролей , который обеспечивает оболочку вокруг crypt(). Этот API значительно упрощает задачу хэширования, проверки и повторного хэширования хэшей паролей. Автор также выпустил пакет совместимости (в виде одного password.php файл, который вы просто require используете), для тех, кто использует PHP 5.3.7 и более поздние версии и хочет использовать это прямо сейчас.

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

API предоставляет четыре функции:

  • password_get_info() - возвращает информацию о данном хэш
  • password_hash() - создает хэш пароля
  • password_needs_rehash() - проверяет, соответствует ли данный хэш заданным параметрам. Полезно проверить, соответствует ли хэш вашей текущей методике/схеме затрат, позволяющей при необходимости переписать
  • password_verify() - проверяет, соответствует ли пароль хэшу

На данный момент эти функции принимают константы паролей PASSWORD_BCRYPT и PASSWORD_DEFAULT, которые на данный момент являются синонимами, с той разницей, что PASSWORD_DEFAULT "может изменение в более новых версиях PHP, когда поддерживаются более новые, более сильные алгоритмы хэширования". Использование PASSWORD_DEFAULT и password_needs_rehash() при входе в систему (и повторное использование при необходимости) должно гарантировать, что ваши хэши достаточно устойчивы к атакам методом перебора, практически не работая для вас.

РЕДАКТИРОВАТЬ: Я только что понял, что это кратко упомянуто в ответе Роберта К. Я оставлю этот ответ здесь, так как я думаю, что он содержит немного больше информации о том, как он работает, и о простоте его использования обеспечивает для тех, кто не знает безопасности.

 25
Author: JonoCoetzee, 2014-07-06 14:08:05

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

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

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

$t_hasher = new PasswordHash(8, FALSE);
$hash = $t_hasher->HashPassword($password);

Для проверки пароля можно использовать:

$t_hasher = new PasswordHash(8, FALSE);
$check = $t_hasher->CheckPassword($password, $hash);
 17
Author: rabudde, 2012-06-26 08:05:12

ВЕЩИ, КОТОРЫЕ НУЖНО ЗАПОМНИТЬ

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

СЕРВЕР

ПОРТЫ

Независимо от того, насколько хорошо ваше шифрование, если вы должным образом не защитите сервер, на котором работает PHP и БД, все ваши усилия бесполезны. Наиболее серверы функционируют примерно так же, у них есть порты, назначенные для удаленного доступа к ним либо через ftp, либо через оболочку. Убедитесь, что вы изменили порт по умолчанию, для которого у вас когда-либо было активное удаленное подключение. Не сделав этого, вы фактически заставили злоумышленника сделать на один шаг меньше для доступа к вашей системе.

ИМЯ ПОЛЬЗОВАТЕЛЯ

Для всего хорошего в мире не используйте имя пользователя admin, root или что-то подобное. Также, если вы работаете в системе на базе unix НЕ делайте доступным вход в учетную запись root, он всегда должен быть только для sudo.

ПАРОЛЬ

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

БАЗА ДАННЫХ

СЕРВЕР

В идеале вы хотите, чтобы ваша база данных и ПРИЛОЖЕНИЕ находились на отдельных серверах. Это не всегда возможно из-за стоимости, но это обеспечивает некоторую безопасность, так как злоумышленнику придется выполнить два шага, чтобы полностью получить доступ к системе.

ПОЛЬЗОВАТЕЛЬ

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

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

Как всегда, НЕ делайте этот корень или что-то в этом роде аналогично.

ПАРОЛЬ

Следуйте тем же рекомендациям, что и при использовании всех надежных паролей. Также не используйте один и тот же пароль повторно на любом СЕРВЕРЕ или учетных записях БД в одной и той же системе.

PHP

ПАРОЛЬ

НИКОГДА НЕ храните пароль в своей БД, вместо этого храните хэш и уникальную соль, я объясню почему позже.

ХЕШИРОВАНИЕ

ОДНОСТОРОННЕЕ ХЕШИРОВАНИЕ!!!!!!!, Никогда не хэшируйте пароль таким образом, чтобы его можно было отменить, Хэши должно быть в одну сторону, то есть вы не отменяете их и не сравниваете с паролем, вместо этого вы хэшируете введенный пароль таким же образом и сравниваете два хэша. Это означает, что даже если злоумышленник получит доступ к базе данных, он не знает, что на самом деле представляет собой пароль, а только его результирующий хэш. Что означает большую безопасность для ваших пользователей в наихудшем из возможных сценариев.

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

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

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

ЗАСОЛКА

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

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

ПОЛЬЗОВАТЕЛИ, СОЗДАЮЩИЕ ПАРОЛИ

Если пользователь создает пароль через интерфейс, это означает, что он должен быть отправлен на сервер. Это создает проблему безопасности, потому что это означает, что незашифрованный пароль отправляется на сервер, и если злоумышленник может прослушивать и получать доступ, вся ваша безопасность в PHP бесполезна. ВСЕГДА передавайте данные БЕЗОПАСНО, это делается через SSL, но будьте утомленный даже SSL не безупречен (недостаток OpenSSL в Heartbleed - пример этого).

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

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

Вот класс PHP, который легко создает хэш и соль для пароля

Http://git.io/mSJqpw

 13
Author: wmfrancia, 2014-07-07 19:38:53

Google говорит, что SHA256 доступен для PHP.

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

 12
Author: AticusFinch, 2008-12-30 22:20:54

Я нашел идеальную тему по этому вопросу здесь: https://crackstation.net/hashing-security.htm , я хотел, чтобы вы извлекли из этого выгоду, вот также исходный код, который также обеспечивал защиту от атаки, основанной на времени.

<?php
/*
 * Password hashing with PBKDF2.
 * Author: havoc AT defuse.ca
 * www: https://defuse.ca/php-pbkdf2.htm
 */

// These constants may be changed without breaking existing hashes.
define("PBKDF2_HASH_ALGORITHM", "sha256");
define("PBKDF2_ITERATIONS", 1000);
define("PBKDF2_SALT_BYTES", 24);
define("PBKDF2_HASH_BYTES", 24);

define("HASH_SECTIONS", 4);
define("HASH_ALGORITHM_INDEX", 0);
define("HASH_ITERATION_INDEX", 1);
define("HASH_SALT_INDEX", 2);
define("HASH_PBKDF2_INDEX", 3);

function create_hash($password)
{
    // format: algorithm:iterations:salt:hash
    $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));
    return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" .  $salt . ":" . 
        base64_encode(pbkdf2(
            PBKDF2_HASH_ALGORITHM,
            $password,
            $salt,
            PBKDF2_ITERATIONS,
            PBKDF2_HASH_BYTES,
            true
        ));
}

function validate_password($password, $good_hash)
{
    $params = explode(":", $good_hash);
    if(count($params) < HASH_SECTIONS)
       return false; 
    $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]);
    return slow_equals(
        $pbkdf2,
        pbkdf2(
            $params[HASH_ALGORITHM_INDEX],
            $password,
            $params[HASH_SALT_INDEX],
            (int)$params[HASH_ITERATION_INDEX],
            strlen($pbkdf2),
            true
        )
    );
}

// Compares two strings $a and $b in length-constant time.
function slow_equals($a, $b)
{
    $diff = strlen($a) ^ strlen($b);
    for($i = 0; $i < strlen($a) && $i < strlen($b); $i++)
    {
        $diff |= ord($a[$i]) ^ ord($b[$i]);
    }
    return $diff === 0; 
}

/*
 * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
 * $algorithm - The hash algorithm to use. Recommended: SHA256
 * $password - The password.
 * $salt - A salt that is unique to the password.
 * $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.
 * $key_length - The length of the derived key in bytes.
 * $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.
 * Returns: A $key_length-byte key derived from the password and salt.
 *
 * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
 *
 * This implementation of PBKDF2 was originally created by https://defuse.ca
 * With improvements by http://www.variations-of-shadow.com
 */
function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
{
    $algorithm = strtolower($algorithm);
    if(!in_array($algorithm, hash_algos(), true))
        die('PBKDF2 ERROR: Invalid hash algorithm.');
    if($count <= 0 || $key_length <= 0)
        die('PBKDF2 ERROR: Invalid parameters.');

    $hash_length = strlen(hash($algorithm, "", true));
    $block_count = ceil($key_length / $hash_length);

    $output = "";
    for($i = 1; $i <= $block_count; $i++) {
        // $i encoded as 4 bytes, big endian.
        $last = $salt . pack("N", $i);
        // first iteration
        $last = $xorsum = hash_hmac($algorithm, $last, $password, true);
        // perform the other $count - 1 iterations
        for ($j = 1; $j < $count; $j++) {
            $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
        }
        $output .= $xorsum;
    }

    if($raw_output)
        return substr($output, 0, $key_length);
    else
        return bin2hex(substr($output, 0, $key_length));
}
?>
 8
Author: Jason OOO, 2013-09-19 13:26:29

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

 7
Author: Max, 2008-12-30 22:29:28

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

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

 6
Author: rmeador, 2008-12-30 22:18:25

SHA1 и соли должно быть достаточно (в зависимости, естественно, от того, кодируете ли вы что-то для Форт-Нокса или системы входа в свой список покупок) в обозримом будущем. Если SHA1 недостаточно хорош для вас, используйте SHA256.

Идея соли состоит в том, чтобы, так сказать, вывести результаты хеширования из равновесия. Известно, например, что MD5-хэш пустой строки равен d41d8cd98f00b204e9800998ecf8427e. Итак, если бы кто-то с достаточно хорошей памятью увидел этот хэш и знал, что это хэш пустой строки. Но если строка пересолена (скажем, со строкой "MY_PERSONAL_SALT"), хэш для "пустой строки" (т.Е. "MY_PERSONAL_SALT") становится aeac2612626724592271634fb14d3ea6, следовательно, неочевидным для обратного отслеживания. Я пытаюсь сказать, что лучше использовать любую соль, чем не использовать. Поэтому не так уж важно знать , какую соль использовать.

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

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

 4
Author: Henrik Paul, 2008-12-30 22:29:51

Хорошо , в fitsy нам нужна соль , соль должна быть уникальной , поэтому давайте сгенерируем ее

   /**
     * Generating string
     * @param $size
     * @return string
     */
    function Uniwur_string($size){
        $text = md5(uniqid(rand(), TRUE));
        RETURN substr($text, 0, $size);
    }

Также нам нужен хэш Я использую sha512 это лучшее, и оно есть в php

   /**
     * Hashing string
     * @param $string
     * @return string
     */
    function hash($string){
        return hash('sha512', $string);
    }

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

// generating unique password
$password = Uniwur_string(20); // or you can add manual password
// generating 32 character salt
$salt = Uniwur_string(32);
// now we can manipulate this informations

// hashin salt for safe
$hash_salt = hash($salt);
// hashing password
$hash_psw = hash($password.$hash_salt);

Теперь нам нужно сохранить в базе данных значение переменной $hash_psw и переменную $salt

И для авторизации мы будем использовать те же шаги...

Это лучший способ защитить пароли наших клиентов...

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

 -5
Author: shalvasoft, 2015-10-08 04:05:05