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

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

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

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

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

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

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

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

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


person luiscubal    schedule 30.12.2008    source источник
comment
openwall.com/phpass - тоже очень хорошая библиотека.   -  person Alfred    schedule 02.07.2011
comment
Md5 теперь совершенно небезопасно   -  person JqueryToAddNumbers    schedule 06.07.2012
comment
@NSAwesomeGuy Это зависит от того, для чего вы его используете. Несложные пароли MD5 без солей и грубой силы, конечно, тривиально, но при приличном подсолении все равно чрезвычайно непрактично построить радужную таблицу для быстрого взлома наборов паролей, а грубая сила - бесполезна.   -  person Craig Ringer    schedule 24.08.2012
comment
PHP 5.5+ имеет безопасный хэш пароля, встроенный в php.net/manual/en/ function.password-hash.php   -  person Terence Johnson    schedule 01.01.2013
comment
php.net/faq.password   -  person hakre    schedule 27.06.2013
comment
Также см. Portable PHP-фреймворк хеширования паролей (PHPass). Он защищен от ряда распространенных атак на пароли пользователей.   -  person jww    schedule 12.10.2014
comment
Встроен с v5.6 php.net/manual/en/function .password-hash.php   -  person NVRM    schedule 09.04.2021


Ответы (14)


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

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

Тем не менее, теория ответа все еще хорошо читается.

TL;DR

Не делать

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

Dos

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

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

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

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

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

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

(Акцент мой.)

В любом случае, что делает пароль хорошим?

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

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

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

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

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

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

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

Bcrypt и scrypt - это современные лучшие практики. Scrypt со временем будет лучше, чем bcrypt, но он не стал стандартом для Linux. / Unix или веб-серверами, и еще не опубликовал подробных обзоров своего алгоритма. Но все же будущее алгоритма выглядит многообещающим. Если вы работаете с Ruby, вам поможет scrypt gem, а теперь в 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.

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

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

person Robert K    schedule 30.12.2008
comment
Понятно. Но в моем случае у человека может быть несколько электронных писем. Должен ли я использовать вместо этого идентификатор (первичный ключ BIGINT)? - person luiscubal; 31.12.2008
comment
@luiscubal: если значения вашей соли взяты из достаточно большого пространства, это будет хорошая соль. Вероятно, вашего значения идентификатора будет достаточно, особенно если количество записей велико (количество идентификаторов будет большим). - person rmeador; 31.12.2008
comment
вы можете использовать все, что есть у пользователя, но в идеале то, что не меняется. - person Tom Haigh; 31.12.2008
comment
Я бы тоже добавил кое-что секретное. Дело в том, что вы хотите, чтобы ввод хэш-функции был согласован для правильного пароля, но вы также хотите, чтобы его нельзя было определить, чтобы кто-то не мог угадать пароль грубой силой в автономном режиме. (вместо того, чтобы делать это через вашу веб-страницу, что намного медленнее) - person Jason S; 31.12.2008
comment
секрет не помогает, поскольку ваша база данных паролей в любом случае должна быть секретной - если они могут получить эту базу данных, они также могут найти любой секрет, который вы используете. однако важно, чтобы соль была случайной. - person frankodwyer; 31.12.2008
comment
обратите внимание, на самом деле неправда, что «вычислительной мощности для расшифровки» еще не существует. поскольку большинство паролей являются словарными словами или производными словарями, атака по словарю обычно очень эффективна (отсюда и использование политик паролей и счетчиков итераций). - person frankodwyer; 31.12.2008
comment
Фрэнк, хотя то, что вы говорите, правда, алгоритмические циклы, необходимые для генерации слов, не делают это возможным. Не забудьте добавить соль. Грубая сила всегда будет работать, если они знают ваш алгоритм хеширования и соль, в противном случае это практически невозможно. - person Robert K; 31.12.2008
comment
Но это не делает небезопасные пароли безопаснее. Это просто делает строки базы данных более безопасными в случае взлома, после чего вы должны немедленно изменить свою соль и сообщить своим пользователям об изменении их паролей. - person Robert K; 31.12.2008
comment
Даже когда соль и алгоритм известны, поиск пароля методом перебора займет много лет, если будет использован правильный метод. Пароли взламываются, когда они предсказываются по шаблону, например, при преобразовании словарных слов и включении других шпаргалок. Существенной частью метода является своего рода вычислительно-интенсивная техника растягивания ключей, например, использование тысяч итераций хеш-функции. - person erickson; 11.05.2009
comment
42, если бы я проектировал действительно безопасную систему, я бы все равно предложил хэш-алгоритм военного уровня с ~ 16-битным случайно сгенерированным числом, хранящимся в базе данных. В общем случае лучше использовать соль с паролем, чем ничего, если только одна из них не скомпрометирована. Я не претендую на звание эксперта, нет ничего лучше принудительной ротации паролей плюс алгоритм военного уровня, но для базового некритичного программного обеспечения этого достаточно. - person Robert K; 26.05.2009
comment
@ злая блоха, я с тобой не спорю. Просто укажу, насколько запутанна и сложна эта область нашей работы. Я продолжаю надеяться, что меня научат самым умным и лучшим методам настройки системы управления контентом небольшого веб-сайта. Я все еще здесь учусь. ... каждый раз, когда я читаю что-то, что имеет смысл, я вскоре замечаю еще 5 сообщений, которые противоречат этому. от этого круговорота быстро закружится голова :) - person m42; 26.05.2009
comment
Абсолютно! Я только что поделился тем, что нашел. Я нашел несколько вещей от Шнайера о безопасности и очень долгое (запутанное) обсуждение на новостном сайте (не помню, какие именно). - person Robert K; 26.05.2009
comment
Даже MD5 по-прежнему безопасен, за исключением атаки методом перебора, вычислительной мощности, необходимой для расшифровки, пока нет. Боже мой, я в это не верю. MD5 нельзя расшифровать, точка. Но это определенно небезопасно и так. Вы когда-нибудь слышали о радужных таблицах? - person o0'.; 05.05.2010
comment
Послушайте, если вы используете MD5 в программном обеспечении, требующем высокой безопасности (например, в магазине), то Дурак ВЫ, а не я. Я знаю, что MD5 очень быстр, но если вы разрабатываете программное обеспечение для форумов с использованием передовых методов, оно все равно в целом безопасно. - person Robert K; 20.05.2010
comment
Интересная доработка. Является ли идентификатор пользователя (скажем, BIGINT с автоматическим увеличением) хорошим одноразовым значением? Или, поскольку это не случайно, это нехорошо? Кроме того, мне придется хранить одноразовый номер для каждого пользователя в базе данных ... Обеспечивает ли ключ сайта + одноразовый номер + HMAC значительно улучшенную безопасность по сравнению с соленым (с идентификатором пользователя) хешем, повторяемым несколько раз? Точно так же, повторение HMAC несколько раз полезно для безопасности? - person luiscubal; 08.07.2010
comment
Отличный пост. Ответил на многие свои вопросы. Однако я не уверен, что значит сохранить site_key в файловой системе. Не могли бы вы объяснить? Для меня даже файл .php в папке на сервере - это файловая система. - person Francisc; 05.04.2011
comment
Статья, в которой 42 связана с ошибками 404 - вот копия chargen.matasano.com/chargen/2007/9/7/ - person Drew Stephens; 08.06.2011
comment
Я когда-нибудь обновлю его о bcrypt. Я был занят, и предложенная мною схема, по крайней мере, умеренно эффективна. Лучше это, чем кто-то просто бросит простой хешированный пароль md5 / sha1 в свою БД. - person Robert K; 16.08.2011
comment
нет другого способа сохранить случайное число $ nonce, кроме как сохранить его в db? Если хакер может получить hashed_password из db, он также может получить nonce из db - person zac1987; 02.01.2012
comment
Отличная доработка. Я использую bcrypt уже некоторое время, и, думаю, я начну изучать scrypt для будущих проектов. - person luiscubal; 25.05.2012
comment
Я думаю, что даже отправить новый пароль по электронной почте в случае утери - плохая идея. Почему бы не отправить по электронной почте ссылку на безопасный сайт, который позволяет пользователю изменить свой пароль? Это намного удобнее (нет необходимости менять пароль после входа в систему со случайным паролем) и более безопасно, поскольку пароль не передается по сети в незашифрованном виде - помните, пользователи ленивы и велики шансы, что они не изменят случайный пароль. - person ThiefMaster; 11.06.2012
comment
Отправка временного пароля по электронной почте, требующая от пользователя изменения его при первом использовании, и отправка защищенной ссылки по электронной почте, которая позволяет им установить свой пароль, также опасны. В любом случае любой, кто перехватывает электронную почту, может получить доступ к учетной записи, если использует ссылку или пароль до того, как это сделает предполагаемый получатель. - person Tim Gautier; 03.08.2012
comment
Что касается вашего последнего редактирования: требуется как минимум 1 буква в верхнем регистре, 1 буква в нижнем регистре, число и символ прямо противоречат комиксу xkcd в ссылке. Он показывает пример пароля с без символов, но с высокой энтропией. - person luiscubal; 06.01.2013
comment
@luiscubal Я не уверен, что Рэндалл прав, поэтому я не поддерживаю его предложение на 100%, хотя я пробовал его. С нижним регистром / пробелами ваша энтропия составляет ~ 4,75 / символ, что для 28 символов составляет около 131-133 бит энтропии. Но там всего четыре слова, с ~ 1 миллионом слов в английском языке, что составляет 1e + 24 комбинации по сравнению с верхними / нижними / символами из 28 символов, что составляет 3,18855e + 55 или около того. Во всяком случае, я не уверен на 100%. - person Robert K; 07.01.2013
comment
@RobertK Люди - несовершенные генераторы случайных чисел, что значительно снижает энтропию в обоих случаях. Они не выберут совершенно случайную [a-zA-Z0-9_$%#]{28} последовательность - они, скорее всего, просто выберут что-то вроде $justinBieber28. - person luiscubal; 07.01.2013
comment
@luiscubal Вы правы. Однако менеджер паролей, который может это сделать, бесценен. Это еще одна проблема с предложением Рэндалла: его метод создает псевдослучайные комбинации, менее случайные, чем наши псевдослучайные пароли с тарабарщиной. Поэтому это было всего лишь предложение чем-то заняться. Один, вероятно, так же безопасен, как и другой (на данный момент). - person Robert K; 07.01.2013
comment
@RobertK Обратите внимание, что он никогда по-настоящему не проверяет энтропию полной тарабарщины, потому что люди, как правило, не используют полную тарабарщину для паролей. Сгенерированные компьютером пароли могут быть намного лучше, чем пароли, созданные человеком, но сколько людей просто нажали бы кнопку «Восстановить», пока не получили что-то, что легко запомнить? Или даже сделать результат проще? Все это снижает энтропию. - person luiscubal; 07.01.2013
comment
@luiscubal Я сказал, что пароль менеджер, а не просто генератор. Я лично использую LastPass для генерации / запоминания паролей и просто создаю лучший пароль, который я могу, чтобы заблокировать эту службу. Это поддерживает высокую энтропию для других сайтов. Как пользователь, это лучшее решение, с которым я когда-либо сталкивался. - person Robert K; 07.01.2013
comment
Просто прочтите обновление, и оно выглядит намного лучше. Удаление моего -1. Возможно, стоит упомянуть новые API 5.5: php.net/manual/en/ref .password.php и проект совместимости: github.com/ircmaxell/password_compat И спасибо за актуализацию ответ !!! - person ircmaxell; 15.01.2013
comment
Требование по крайней мере 1 буквы верхнего регистра, 1 буквы нижнего регистра, числа и символа не улучшит энтропию пароля, это только затруднит запоминание людьми. - person Popnoodles; 19.01.2013
comment
@popnoodles Расширяя набор символов и количество используемых символов, он увеличивает бит энтропии на символ, он НЕ защищает от неслучайных паролей пользователей. - person Robert K; 21.01.2013
comment
@RobertK Расширяя набор символов, да, он увеличивается, НО, заставляя все пароли следовать правилам, уменьшает количество возможных вариантов. Допустим, кто-то должен был получить пароль грубой силой. Сообщив им, что пароль пользователя состоит из 1 буквы в верхнем регистре, 1 буквы в нижнем регистре, числа и символа, это означает, что количество необходимых им попыток значительно меньше. Позволяя пользователю решать, чего он хочет, хакер должен стараться изо всех сил. - person Popnoodles; 25.01.2013
comment
@popnoodles Это отличный момент, который я полностью упустил: я предложил установить жесткое требование, ограничивающее количество возможных открытых текстов. Спасибо что подметил это! - person Robert K; 25.01.2013
comment
Это улучшит энтропию пароля - если вы заставите кого-то использовать хотя бы одно число, вы уменьшите энтропию пароля, так как есть только 10 цифр на выбор. - person PP.; 12.09.2013
comment
@RobertK, не уверен, почему ты лично атаковал меня сарказмом - версия с утонченными нотками. Прошу модераторов временно отстранить вас, потому что она вышла из строя. - person PP.; 13.09.2013
comment
@PP. Я не понимаю, что вы читаете как сарказм. Раздел TL; DR в верхней части моего ответа - это версия длинной части моего ответа в виде скальных заметок. Все, что я просил, это ответить на конкретные вопросы в соответствующем разделе, а не на краткое изложение TL; DR, которое не содержит никаких дискуссий по этому вопросу. - person Robert K; 13.09.2013
comment
Также рассмотрите возможность хеширования на стороне клиента, таким образом, даже если сервер каким-либо образом был поврежден, исходные пароли не могут быть восстановлены! - person ; 07.11.2013
comment
@derylius Если ваш код входа в систему не предоставлен в виде плагина, вы не можете проверить, является ли код javascript вашим исходным кодом без каких-либо компромиссов. Кроме того, отправка хэша для сравнения с хешем в БД не менее опасна (он заменяет пароль). Это не очень хорошая или безопасная идея. Лучше полагаться на безопасность соединения, чем на безопасность javascript. - person Robert K; 07.11.2013
comment
@RobertK Думаю, вы меня неправильно поняли. Я не говорил делать это вместо того, чтобы устанавливать безопасное соединение, я предложил сделать это дополнительно, потому что, даже если соединение является безопасным, если сервер будет скомпрометирован, тогда каждый отдельный запрос, отправленный на этот сервер, потенциально показывает простой пароли к злоумышленникам. Итак, я хочу сказать, что как пользователь я не хочу доверять никакому серверу, но это не значит, что я хочу запомнить хеш-строку длиной 64 символа вместо цвета моего любимого фрукта. (Дальнейшее объяснение здесь: xkcd.com/936) - person ; 07.11.2013
comment
@derylius Да, наверное, я неправильно понял. Однако отправлять хеш на сервер так же плохо. Хотя я думаю, что SQRL Стива Гибсона очень перспективен. - person Robert K; 07.11.2013
comment
@RobertK - это всего лишь небольшое дополнение, которое защищает сам пароль, а не среду. Но поскольку пароли в любом случае должны быть хешированы для их хранения, хеширование на стороне клиента, а не на стороне сервера, - это не столько лишний код, который добавляет часть безопасности, не убирая ее. - person ; 08.11.2013
comment
Я также считаю, что срок действия паролей не должен истекать. Принуждение пользователей к созданию новых паролей и запрет им использовать ранее использованные пароли приводит к тому, что пользователи выбирают все более и более худшие комбинации, поскольку они никогда не могут их вспомнить. Конечно, они все равно не должны вспоминать, но я говорю о реальности, а не об идеальном мире. - person MrYellow; 05.11.2014
comment
@MrYellow Вообще мне тоже не нравится истечение срока действия пароля. Но предотвращение использования предыдущих паролей - хорошая идея для приложений с высоким уровнем безопасности. В конце концов, вы бы не хотели, чтобы кто-то менял пароли на чем-то очень важном. Но я не учел их, потому что они казались субъективными выводами. Это сложнее доказать, чем алгоритм X может быть вычислен в Y M-хэшах / сек. - person Robert K; 05.11.2014
comment
@RobertK Я слышал стратегии от людей, которые просто сбрасывают свой пароль 15 раз, чтобы истечь ранее использованный список и вернуться к паролю, который они могут запомнить ... да, согласны, цифры не являются резкими в этой части вопрос. Это спорно, и правильный выбор зависит от назначения системы. - person MrYellow; 05.11.2014
comment
@MrYellow Да, я не удивлен. Примерно единственный способ, которым будет работать схема истечения срока действия пароля, - это если прошлые пароли были сохранены, а расстояние Левенштейна использовалось для проверки нового пароля. Это деспотично, но это единственный способ убедиться, что пользователи не выбирают пароль, затем пароль1, затем пароль2 и т. Д. (Не то чтобы я советую это делать ...) - person Robert K; 06.11.2014
comment
Что касается принуждения пользователей вводить пароль с каждым типом символов: во-первых, это разозлит их и заставит уйти, во-вторых, это даже не нужно / полезно. Вместо этого просто начните блокировать учетную запись после слишком большого количества попыток / слишком быстрых попыток. Даже если вы просто ограничите его до 1 попытки ввода пароля в секунду, вы искалечили возможности взломщика грубой силы, не так ли? - person Andrew; 28.10.2015
comment
Как восстановить пароль, если его забыли пользователи? - person Iman Marashi; 08.11.2015
comment
@ImanMarashi, как я бы это сделал (и, пожалуйста, поправьте меня, если я тупица: P): создайте страницу с забытым паролем и позвольте ему заполнить поле своим адресом электронной почты. Когда пользователь нажимает кнопку "Отправить", вы генерируете случайный пароль , возможно, это поможет ( который, конечно, должен быть снова хеширован) и отправьте ему электронное письмо со случайным паролем внутри и ссылкой на страницу его учетной записи и попросите его сменить пароль. Вот как бы я это сделал, может я совершенно ошибаюсь, но тогда мне интересно посмотреть, как это должно быть сделано - person BRoebie; 29.12.2015
comment
@BRoebie Я не советую менять пароль пользователя, потому что кто-то, ловящий пользователей / электронные письма, может заблокировать пользователей. Вместо этого сгенерируйте токен с коротким сроком действия (например, 15 минут) и используйте этот токен в ссылке электронного письма на страницу сброса. Так безопаснее. Но сброс паролей по электронной почте никогда не бывает особенно безопасным (IMO). - person Robert K; 30.12.2015
comment
Спасибо за ваш ответ. Я обязательно воспользуюсь этим методом. Я поищу в Интернете несколько примеров. Не могли бы вы дать мне отметку времени, которую я должен использовать до истечения срока ее действия. Например, будет ли приемлемым и час? Я знаю, что это будет менее безопасно, но некоторые почтовые службы работают довольно медленно - person BRoebie; 30.12.2015
comment
Я не согласен с тем, что требуются прописные буквы, строчные буквы, числа и символы одновременно. Все, что нужно сделать, это заставить людей вводить Пароль1! вместо пароля. Или, что еще хуже, они запишут это на стикерах. Такие ограничения неактуальны для пользователей диспетчера паролей, но даже в этом случае не применяйте такие жесткие ограничения, если вы не являетесь банком или платежной службой. - person Hugo Zink; 12.01.2016
comment
Вместо scrypt и bcrypt в настоящее время вам, вероятно, стоит обратить внимание на argon2, который выиграл соревнование по хешированию паролей. - person Thom Wiggers; 03.02.2016
comment
Ограничение пароля до <200 символов - это нормально, ИМХО; если бы пользователь ввел только 0s и 1s, у них все равно была бы в основном нерушимая энтропия или, ради аргумента, 1000 символов. Нет смысла идти по пути, способу более 256 бит энтропии, просто чтобы сказать, что нет предела. Вы счастливы хэшировать пароль размером в несколько ГБ, который я вам даю? Альтернативный обходной путь: заставьте пользователя хешировать свой пароль на 50 ГБ с помощью SHA-2 или чего-то еще и притвориться, что это пароль. Бам, все «пароли», которые вы получаете, имеют длину 32 байта (хотя для его хранения все же нужно использовать хеш-пароль). - person Nick T; 01.10.2018
comment
@NickT Большинство веб-серверов отклонят пароль на 50 ГБ из-за превышения пределов загрузки и тайм-аута при вводе, поэтому я считаю, что этот вопрос спорный. Пока ваш лимит составляет 64+, на мой взгляд, его можно найти. (Однако вы можете проверить возраст этого ответа.) ???? - person Robert K; 04.10.2018

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

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

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

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

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

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

Все это потому, что Windows по-прежнему не изменяет и не растягивает свои пароли, даже в Windows 10. Так будет и в 2021 году. Не совершайте ту же ошибку, что и Microsoft!

См. также:

  • отличный ответ с более подробной информацией о том, почему password_hash() или phpass - лучший способ пойти.
  • хорошая статья в блоге, дающая рекомендуемые« рабочие факторы »(количество итераций) для основных алгоритмов, включая bcrypt, scrypt и PBKDF2.
person RichVel    schedule 08.11.2011
comment
но эти системы более известны и, возможно, уже взломаны. но лучше делать самому, когда не знаешь, что делаешь. - person JqueryToAddNumbers; 12.02.2012
comment
Эти системы более известны и, возможно, уже скомпрометированы - нет причин, по которым хорошо спроектированная система аутентификации должна быть скомпрометирована только потому, что она более известна. Библиотеки, такие как phpass, написаны экспертами и подробно проверены многими людьми - тот факт, что они хорошо известны, сопровождается подробным обзором разными людьми и, скорее всего, означает, что они безопасны. - person RichVel; 16.02.2012
comment
Учитывая недавние дампы хэшей паролей от LinkedIn, Last.fm и других, это весьма актуально. Вы попали в хорошую компанию, не зная, как написать собственный механизм паролей! - person RichVel; 05.07.2012
comment
вообще не пишите свой собственный механизм паролей - но истинные параноики захотят написать свой собственный, чтобы свести к минимуму вероятность того, что у АНБ есть бэкдор. - person PP.; 12.09.2013
comment
@PP - шансы, что проверенный алгоритм хеширования паролей имеет бэкдор АНБ, на мой взгляд, очень низок. Шансы того, что кто-то, не являющийся настоящим экспертом в области криптографии, напишет новый механизм хеширования паролей без других уязвимостей, намного ниже. И типичное веб-приложение использует только хеширование MD5 или SHA-1, что ужасно - даже в отличной книге Криса Шифлетта Essential PHP Security рекомендуется MD5 ... - person RichVel; 14.09.2013
comment
phpass - НЕ лучший способ. Никогда не было и, скорее всего, никогда не будет. Я просмотрел код несколько лет назад, и он НЕ безопасен в Windows или любой платформе, где / dev / urandom недоступен. Когда дело доходит до безопасности, он НЕ следует передовым практикам, используя комбинацию md5 () и microtime (), когда он должен завершать приложение вместо того, чтобы делать ложные заявления о безопасности. Он не видел никаких обновлений с тех пор, как я просмотрел код, несмотря на то, что сам PHP продвигается вперед в области безопасности с bcrypt в ядре. Держитесь подальше от phpass. - person CubicleSoft; 08.02.2015
comment
@CubicleSoft - можете ли вы порекомендовать другую библиотеку PHP для хеширования паролей? Если не будет лучшей библиотеки, phpass все равно будет лучше, чем подавляющее большинство настраиваемого кода, использующего несоленый и нерастянутый MD5. - person RichVel; 09.02.2015
comment
@RichVel - Функция password_hash (). Как упоминалось ранее, он встроен в ядро ​​PHP (также известное как / ext / standard). - person CubicleSoft; 15.03.2015
comment
@CubicleSoft - password_hash () по умолчанию имеет значение bcrypt и имеет функцию стоимости для растягивания, поэтому он кажется хорошим для людей с PHP 5.5 или выше - php.net/manual/en/function.password-hash.php. phpass поддерживает более ранние версии PHP, где он, безусловно, лучше, чем пользовательский код большинства людей, построенный на MD5 и т. д. - person RichVel; 19.03.2015

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

person Tom Haigh    schedule 30.12.2008
comment
не для хеширования паролей. злоумышленнику достаточно взломать один хэш, чтобы получить пароль. в любом случае это спорный вопрос, поскольку ни MD5, ни SHA1 не имеют каких-либо практических разрывов в сценарии пароля. - person frankodwyer; 31.12.2008
comment
извините, я неправильно истолковал ваш ответ как рекомендацию использовать два хэша ... вы на самом деле правы. Использование двух хешей ослабляет систему в случае пароля, поскольку им нужно только взломать более слабый хеш. - person frankodwyer; 31.12.2008

Начиная с 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() подхватывает его.

person AlliterativeAlice    schedule 21.09.2014

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

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

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

person Gaurav Kumar    schedule 12.02.2010
comment
Даже если злоумышленник получает соль, строка sitealt: usersalt: password по-прежнему устойчива к предварительно вычисленным таблицам, поскольку злоумышленнику необходимо сгенерировать таблицы для каждого пользователя (так что атака становится намного медленнее), если, конечно, не используется конкретный пользователь. целевой ... - person luiscubal; 12.02.2010
comment
Что касается: Даже если злоумышленник поймет, что строка пароля sitealt: usersalt: по-прежнему устойчива к предварительно вычисленным таблицам, полностью согласен. Я хочу сказать, что sitealt, если он сделан случайным и длинным, сделает систему более безопасной, чем она (sitealt) предсказуема. Я видел, как некоторые люди рекомендовали использовать идентификатор электронной почты и т. Д. В качестве соли, и я не одобряю этого. - person Gaurav Kumar; 13.02.2010
comment
Вы пропустили то, что я написал изначально. Я сказал использовать случайный одноразовый номер, хранящийся вместе с записью, ПЛЮС адрес электронной почты. Добавление адреса электронной почты увеличивает энтропию для работы хакера. С тех пор я переписал свой ответ в пользу bcrypt. - person Robert K; 23.03.2012

Я просто хочу отметить, что 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 () при входе в систему (и повторное хеширование при необходимости) должно гарантировать, что ваши хэши достаточно устойчивы к атакам методом грубой силы, практически не выполняя для вас никакой работы.

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

person JonoCoetzee    schedule 27.04.2013

Я использую 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);
person rabudde    schedule 26.06.2012

ЧТО ПОМНИТЬ

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

СЕРВЕР

ПОРТЫ

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

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

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

ПАРОЛЬ

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

БАЗА ДАННЫХ

СЕРВЕР

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

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

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

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

Вроде всегда НЕ делайте этот рут или что-то подобное.

ПАРОЛЬ

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

PHP

ПАРОЛЬ

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

ХЭШИНГ

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

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

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

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

СОЛЕНИЕ

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

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

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

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

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

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

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

http://git.io/mSJqpw

person wmfrancia    schedule 09.04.2014
comment
Вы должны исключить SHA512 из своего списка достойных алгоритмов хеширования, потому что это слишком быстро. Используйте его только в сочетании с PBKDF2. В то время как BCrypt основан на blowfish, сам blowfish является алгоритмом для шифрования, а не для хеширования. - person martinstoeckli; 09.04.2014
comment
Как вы храните случайную соль в БД? Я думаю, вы не хешируете его (нельзя использовать для проверки) и не храните в открытом виде (нет реальных преимуществ, если злоумышленник может читать БД). Итак, как вы это делаете? - person Iazel; 13.06.2014
comment
wmfrancia писал: «Соление» добавляет к паролю случайную строку, поэтому похожие пароли не отображаются одинаково в БД. Для меня это не имеет смысла. Хэши в БД уже будут выглядеть непохожими, потому что это свойство хеш-функций. - person H2ONaCl; 26.02.2015
comment
wmfancia пишет о постоянной соли: как только злоумышленник вычисляет одну соль пароля, он получает соль для всех. То же самое можно сказать, что если хакер выясняет, какое поле БД является солью, у него есть соли для всех из них. Поскольку постоянная соль, вероятно, не будет в базе данных, это хорошо для постоянной соли. - person H2ONaCl; 26.02.2015
comment
Конечно, эти комментарии не предполагают, что случайная соль для каждого пользователя не лучше, чем одна соль для каждого приложения. Это лучше. - person H2ONaCl; 26.02.2015

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

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

person AticusFinch    schedule 30.12.2008
comment
Кому-то хватит 64 бита? - person Konerak; 21.06.2011
comment
@Konerak, я вернусь к этому через 20 лет. :) Но да, SHA256 действительно доступен. Если вы хотите узнать, насколько безопасен SHA256, вы можете проверить это: security.stackexchange.com/questions/90064/ - person Vincent Edward Gedaria Binua; 04.12.2015

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

person Max    schedule 30.12.2008
comment
Множественное хеширование также защищает от атак по словарю и грубой силы, то есть просто заставляет их вычислять больше времени. - person frankodwyer; 31.12.2008
comment
двойное хеширование не даст вам значительного преимущества, но многократные итерации хеширования по-прежнему являются реальной защитой от атак по словарю и брюс-форса. Хэши паролей промышленной надежности используют более 1000 раундов. PBKDF1 PKCS # 5 предлагает минимум 1000 раундов. - person Berk D. Demir; 02.01.2009

Я нашел идеальную тему по этому поводу здесь: 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));
}
?>
person Jason OOO    schedule 19.09.2013
comment
Вы даете нам решение без использования, без использования - person Michael; 05.05.2016

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

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

person rmeador    schedule 30.12.2008
comment
постоянная соль - не лучшая идея ... вероятно, не фатальный недостаток, но излишне ослабляет схему. - person frankodwyer; 31.12.2008
comment
MD5 и SHA1 работают быстро, так что это плохой вариант. - person CodesInChaos; 05.03.2014

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

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

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

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

person Henrik Paul    schedule 30.12.2008
comment
Целевой сайт не должен содержать ничего слишком важного (это не банк), но все же я бы предпочел, чтобы он был защищен. - person luiscubal; 31.12.2008
comment
двойное хеширование не уменьшает пространство результатов. итеративное хеширование является обычным средством защиты от атак по словарю и грубой силы (это замедляет их гораздо больше, чем замедляет проверку пароля). - person frankodwyer; 31.12.2008
comment
@frankodwyer: да, это плохо. sha1(sha1($foo)) эффективно уменьшает пространство вывода, потому что любое столкновение внутренней функции автоматически становится столкновением внешней. Ухудшение линейно, но это все еще вызывает беспокойство. Методы итеративного хеширования возвращают данные в каждом раунде, например $hash = sha1(sha1($salt . $password) . $salt). Но это все равно нехорошо ... Придерживайтесь PBKDF2 или Bcrypt ... - person ircmaxell; 13.09.2012

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

   /**
     * 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 шагов вы можете использовать свой собственный алгоритм ... но убедитесь, что вы сможете сгенерировать этот хешированный пароль в будущем, когда вам потребуется авторизовать пользователя ...

person shalvasoft    schedule 08.10.2015
comment
Этот вопрос касался хешей паролей. 1 выполнение sha512 (даже если он соленый) считается недостаточно эффективным для защиты паролем. (также, что ГСЧ не является криптографически безопасным, поэтому использование его для генерации пароля рискованно). - person luiscubal; 08.10.2015
comment
Вы понятия не имеете, что делаете. Прочтите основные ответы в этом посте, и вы поймете, почему ваш код не просто небезопасен, но и не имеет смысла. - person cryptic ツ; 09.10.2015
comment
Ok. мой код небезопасен. так дайте мне знать, почему вы используете в своих алгоритмах только sha256 ??? Я знаю что sha512 лучший, почему бы не использовать ??? - person shalvasoft; 10.10.2015
comment
@shalvasoft sha512 довольно хорош для хеширования общего назначения, но для защиты паролем требуются хэши с очень специфическими свойствами (например, медлительность - это, как ни странно, хорошая вещь, а sha512 довольно быстрая). Некоторые люди использовали sha512 в качестве строительного блока для создания функций хеширования паролей, но в настоящее время рекомендуется использовать bcrypt и следить за scrypt. - person luiscubal; 11.10.2015