Вопрос

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

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

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

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

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

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

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

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

Это было полезно?

Решение

Отказ от ответственности:Этот ответ был написан в 2008 году.

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

Тем не менее, теорию ответа по-прежнему можно хорошо прочитать.

TL;DR

Не надо

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

Dos

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

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

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

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

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

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

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

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

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

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

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

На сайте есть более подробное обсуждение энтропии паролей. Крипто-стековый обмен Сайт.Хороший поиск в Google также даст много результатов.

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

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

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

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

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

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

Другие советы

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

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

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

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

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

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

Смотрите также:

  • отличный ответ подробнее о том, почему password_hash() или phpass это лучший способ уйти.
  • хорошая статья в блоге дающий рекомендуемые "рабочие коэффициенты" (количество итераций) для основных алгоритмов, включая bcrypt, scrypt и PBKDF2.

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

Начиная с версии PHP 5.5, PHP имеет простые, безопасные функции для хэширования и проверки паролей, пароль_hash() и пароль_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() улавливает это.

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

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

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

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

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

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

По умолчанию он использовал самое надежное доступное шифрование, реализованное в 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);

ЧТО НУЖНО ЗАПОМНИТЬ

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

СЕРВЕР

ПОРТЫ

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

Имя пользователя

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

Пароль

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

База данных

СЕРВЕР

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

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

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

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

Как всегда, НЕ создавайте этот root или что-то подобное.

Пароль

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

PHP

Пароль

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

ХЕШИРОВАНИЕ

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

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

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

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

ЗАСОЛКА

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

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

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

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

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

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

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

http://git.io/mSJqpw

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

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

Я нашел здесь идеальную тему по этому вопросу: 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));
}
?>

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top