Intereting Posts
Приложение Facebook на странице PHP – $ _SESSION не поддерживается, когда пользователь закрывает окно своего браузера Несколько запросов PHP-запросов на сбои Как заменить не SGML-символы в String с помощью PHP? MP4 воспроизводится при доступе напрямую, но не при чтении через PHP, на iOS PHP песочница / дезинфицировать код, переданный create_function неразрывное пространство utf-8 0xc2a0 и preg_replace странное поведение Как добавить динамическое текстовое поле (строка) и сохранить в базу данных с помощью PHP Как использовать OAuth с Календарем Google для доступа только к одному календарю? Может ли GD сделать текст искаженным (чтобы он выглядел так, будто он слегка обтекает кривую)? WordPress: как установить тему по умолчанию (активная) через скрипт Использование Java для анализа XML как удалить parsererror: SyntaxError: Неожиданный токен <в JSON в позиции 0 simplexml, возвращая несколько элементов с тем же тегом Выбор родительских узлов с помощью XMLReader Класс DomDocument не может получить доступ к domnode

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

В настоящее время говорят, что 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 и необработанный вывод hash () , либо используйте hex-выход, либо base64_encode. (Это относится к любому входу, который может содержать в нем жулик \0 , что может серьезно ослабить безопасность).

ДОС

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

Почему хеш-пароли в любом случае?

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

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

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

Интересно, что, выйдя из этого кошмара, я узнал ЛОТ, о котором я не знал о взломе, хранении и сложности паролей. Я пришел к пониманию того, почему хранилище паролей становится гораздо более важным, чем сложность паролей. Если вы не знаете, как хранится ваш пароль, то все, от чего вы действительно можете зависеть, это сложность. Это может быть общим знанием для паролей и криптоваторов, но для среднего специалиста InfoSec или Web Security я очень сомневаюсь в этом.

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

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

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

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

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

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

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

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

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

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

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

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

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

  • PHP 5.5 или выше: password_hash () – это хорошее качество и часть ядра PHP.
  • Старые версии PHP: библиотека php OpenWall намного лучше, чем большинство пользовательских кодов – используется в WordPress, Drupal и т. Д.

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

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

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

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

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

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

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

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

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

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

Начиная с 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() берет на себя.

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

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

Я использую Phpass, который является простым однофайльным PHP-классом, который может быть реализован очень легко почти в каждом проекте PHP. См. Также The 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); 

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

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

SERVER

ПОРТЫ

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

USERNAME

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

ПАРОЛЬ

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

БАЗА ДАННЫХ

SERVER

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

USER

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

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

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

ПАРОЛЬ

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

PHP

ПАРОЛЬ

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

HASHING

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

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

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

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

засол

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

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

ПОЛЬЗОВАТЕЛИ СОЗДАНИЯ ПАРОЛЬ

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

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

Наконец, независимо от того, какие меры безопасности вы ничего не берете, это на 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)); } ?> 

I usually use SHA1 and salt with the user ID (or some other user-specific piece of information), and sometimes I additionally use a constant salt (so I have 2 parts to the salt).

SHA1 is now also considered somewhat compromised, but to a far lesser degree than MD5. By using a salt (any salt), you're preventing the use of a generic rainbow table to attack your hashes (some people have even had success using Google as a sort of rainbow table by searching for the hash). An attacker could conceivably generate a rainbow table using your salt, so that's why you should include a user-specific salt. That way, they will have to generate a rainbow table for each and every record in your system, not just one for your entire system! With that type of salting, even MD5 is decently secure.

SHA1 and a salt should suffice (depending, naturally, on whether you are coding something for Fort Knox or a login system for your shopping list) for the foreseeable future. If SHA1 isn't good enough for you, use SHA256 .

The idea of a salt is to throw the hashing results off balance, so to say. It is known, for example, that the MD5-hash of an empty string is d41d8cd98f00b204e9800998ecf8427e . So, if someone with good enough a memory would see that hash and know that it's the hash of an empty string. But if the string is salted (say, with the string " MY_PERSONAL_SALT "), the hash for the 'empty string' (ie " MY_PERSONAL_SALT ") becomes aeac2612626724592271634fb14d3ea6 , hence non-obvious to backtrace. What I'm trying to say, that it's better to use any salt, than not to. Therefore, it's not too much of an importance to know which salt to use.

There are actually websites that do just this – you can feed it a (md5) hash, and it spits out a known plaintext that generates that particular hash. If you would get access to a database that stores plain md5-hashes, it would be trivial for you to enter the hash for the admin to such a service, and log in. But, if the passwords were salted, such a service would become ineffective.

Also, double-hashing is generally regarded as bad method, because it diminishes the result space. All popular hashes are fixed-length. Thus, you can have only a finite values of this fixed length, and the results become less varied. This could be regarded as another form of salting, but I wouldn't recommend it.

ok in the fitsy we need salt salt must be unique so let generate it

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

also we need the hash I`m using sha512 it is the best and it is in php

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

so now we can use this functions to generate safe password

 // 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); 

now we need to save in database our $hash_psw variable value and $salt variable

and for authorize we will use same steps…

it is the best way to safe our clients passwords…

Ps for last 2 steps you can use your own algorithm… but be sure that you can generate this hashed password in the future when you need to authorize user…