пароли:

от времени я слышу совет: «Используйте bcrypt для хранения паролей в PHP, правила bcrypt».

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

Какое объяснение?

 Andrew Moore09 сент. 2011 г., 00:00
@Vilx: я добавил больше информации о том, почемуbcrypt односторонний алгоритм хеширования по сравнению со схемой шифрованияв моем ответе, Есть все это заблуждение, чтоbcrypt это просто Blowfish, когда на самом деле он имеет совершенно другое расписание ключей, которое гарантирует, что простой текст не может быть восстановлен из текста шифра, не зная исходного состояния шифра (соль, раунды, ключ).
 eykanal23 мая 2011 г., 03:44
Этот вопрос быладресовано ранееи их предложение об использовании стандартной библиотеки превосходно. Безопасность - сложный вопрос, и, используя пакет, разработанный кем-то, кто знает, какого черта они делают, вы только помогаете себе.
 jww12 окт. 2014 г., 01:25
Также см. Openwall'sПереносимая структура хеширования паролей PHP (PHPass). Он защищен от ряда распространенных атак на пароли пользователей.
 Vilx-23 мая 2011 г., 16:44
@eykanal - я не прошу объяснения того, как это работает. я просто хочу знатьчто это. Потому что все, что я могу найти в сети под ключевым словом "bcrypt", никоим образом не может использоваться для хеширования паролей. Во всяком случае, не напрямую и не в PHP. Хорошо, теперь я понимаю, что это действительно пакет "phpass", который использует blowfish для шифрования вашего пароля с помощью ключа, полученного из вашего пароля (по сути, шифрование пароля самим собой). Но упоминание его как «bcrypt» вводит в заблуждение, и это то, что я хотел уточнить в этом вопросе.
 Vilx-23 мая 2011 г., 10:18
@eykanal - на этой странице даже не упоминается bcrypt, а тем более объяснитьчто это.

Ответы на вопрос(9)

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

Самый простой способ использовать эти функции:

$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

Этот код будет хэшировать пароль с помощью BCrypt (алгоритм2y), генерирует случайную соль из случайного источника ОС и использует параметр стоимости по умолчанию (на данный момент это 10). Вторая строка проверяет, соответствует ли введенный пользователем пароль уже сохраненному хеш-значению.

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

$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 11));

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

Для PHP версии 5.3.7 и новее существуетпакет совместимостиот того же автора, который сделалpassword_hash() функция. Для версий PHP до 5.3.7 нет поддержкиcrypt() с участием2y, Unicode безопасный алгоритм BCrypt. Вместо этого можно заменить2a, которая является лучшей альтернативой для более ранних версий PHP.

 jzimmerman201129 авг. 2014 г., 15:20
После того, как я прочитал это, моей первой мыслью было «как вы храните полученную соль»? После просмотра документов функция password_hash () в итоге генерирует строку, в которой хранятся метод шифрования, соль и сгенерированный хэш. Таким образом, он просто хранит все, что ему нужно, в одной строке для работы функции password_verify (). Просто хотел упомянуть об этом, так как это может помочь другим, когда они видят это.
 martinstoeckli29 авг. 2014 г., 15:40
@ jzimmerman2011 - Точно, в другомответ я попытался объяснить этот формат хранения на примере.

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

Также связано, но предосторожно: у злоумышленника никогда не должно быть неограниченного доступа к вашему экрану входа. Чтобы предотвратить это: настройте таблицу отслеживания IP-адресов, которая будет записывать каждое попадание вместе с URI. Если более пяти попыток входа в систему происходит с одного и того же IP-адреса в течение любого пятиминутного периода, заблокируйте объяснение. Вторичный подход заключается в использовании двухуровневой схемы паролей, как это делают банки. Установка блокировки для сбоев на втором проходе повышает безопасность.

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

 Bruce Aldridge14 сент. 2012 г., 11:34
@ Sammaye Я согласен, что постоянные блоки плохие. Я имею в виду временный блок, который увеличивается с количеством неудачных попыток.
 Vilx-07 дек. 2011 г., 23:35
Я думаю, они предполагают, что злоумышленнику уже удалось украсть мою БД с помощью других средств, и теперь пытается вывести пароли, чтобы опробовать их на PayPal или что-то в этом роде.
 Sammaye01 сент. 2012 г., 12:36
@BruceAldridge Лично я думаю, что было бы лучше сделать ваш скрипт приостановленным на случайное время после, скажем, 7 неудачных входов в систему и показывать капчу, а не блокировать. Блокировка - очень агрессивный ход.
 Bruce Aldridge01 сент. 2012 г., 11:37
@ Sammaye Я бы с этим согласился. Я установил блок на 5 неудачных попыток входа в систему, прежде чем быстро повысить его до 7, а затем 10, теперь он сидит на 20. Ни один нормальный пользователь не должен иметь 20 неудачных попыток входа в систему, но его достаточно мало, чтобы легко остановить атаки методом подбора.
 Sammaye14 авг. 2012 г., 17:02
На полпути до 2012 года, и этот ответ все еще сомнительный, как алгоритм медленного хеширования предотвращает атаки радужных таблиц? Я думал, что случайная соль диапазона байтов сделала? Я всегда думал, что скорость алгоритма хеширования определяет, сколько итераций они могут отправить против хэша, который они получили от вас за определенное время. Кроме того, НИКОГДА НЕ ЗАБИРАЙТЕ ПОЛЬЗОВАТЕЛЯ НА НЕУДАЧИХ ПОПЫТКАХ ВХОДА, поверьте мне, ваши пользователи будут сыты по горло, часто на некоторых сайтах мне нужно входить в систему почти 5 раз, иногда больше, прежде чем я запомнил свой пароль для него. Также второй уровень прохода не работает, хотя двухэтапная аутентификация с кодом мобильного телефона могла бы.

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

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

 Arkh25 янв. 2011 г., 17:02
@Josh K. Я рекомендую вам попытаться взломать несколько простых паролей после того, как они настроены через phpass, поэтому для его вычисления на вашем веб-сервере требуется от 1 мс до 10 мс.
 Arkh25 янв. 2011 г., 17:12
Согласовано. Но тип пользователя, который будет использовать qwerty в качестве пароля, также является типом пользователя, который будет отмечать любой сложный, где он (и злоумышленники) могут легко его прочитать. Что делает использование bcrypt, так это то, что, когда ваш БД становится публичным против вашей воли, тем пользователям, у которых есть какой-то пароль, например ^ | $ & ZL6- £, будет сложнее, чем если бы вы использовали sha512 за один проход.
 damianb21 мая 2012 г., 02:17
@coreyward стоит отметить, что делать это более вредно, чем вообще не блокировать; это легко считать вектором отказа в обслуживании. Просто начните рассылать плохие логины на любых известных учетных записях, и вы сможете очень, очень легко нарушить работу многих пользователей. Злоумышленнику лучше отстранить (задержать), чем полностью запретить доступ, особенно если это платящий клиент.
 Arkh25 янв. 2011 г., 16:54
Нет. Хеширование паролей используется для защиты от одной атаки: кто-то украл вашу базу данных и хочет получить логин и пароли в виде открытого текста.
 Arkh25 янв. 2011 г., 16:49
Примените все, что вы хотите, пользователям удастся испортить и использовать один и тот же пароль для нескольких вещей. Таким образом, вы должны максимально защитить его или реализовать что-то, что позволит вам не хранить пароль (SSO, openID и т. Д.).

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

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

Посмотрим правде в глаза, криптография это сложно.

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

Вместо этого просто используйте библиотеку. Несколько существуют в зависимости от ваших требований.

Библиотеки

Вот разбивка некоторых из наиболее распространенных API.

PHP 5.5 API - (доступно для 5.3.7+)

Начиная с PHP 5.5, вводится новый API для хеширования паролей. Также есть поддерживаемая мной библиотека совместимости shim для 5.3.7+. Это имеет то преимущество, что рецензируется ипросто использовать реализацию.

function register($username, $password) {
    $hash = password_hash($password, PASSWORD_BCRYPT);
    save($username, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    if (password_verify($password, $hash)) {
        //login
    } else {
        // failure
    }
}

На самом деле, он призван быть чрезвычайно простым.

Ресурсы:

Документация:на PHP.netБиблиотека совместимости:на GitHubPHP RFC:на wiki.php.netZend \ Crypt \ Password \ Bcrypt (5.3.2+)

Это еще один API, похожий на PHP 5.5 и имеющий аналогичную цель.

function register($username, $password) {
    $bcrypt = new Zend\Crypt\Password\Bcrypt();
    $hash = $bcrypt->create($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $bcrypt = new Zend\Crypt\Password\Bcrypt();
    if ($bcrypt->verify($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Ресурсы:

Документация:на ZendСообщение блога:Хеширование паролей с помощью Zend CryptPasswordLib

Это немного другой подход к хешированию паролей. Вместо того, чтобы просто поддерживать bcrypt, PasswordLib поддерживает большое количество алгоритмов хеширования. Это в основном полезно в тех случаях, когда вам необходимо поддерживать совместимость с устаревшими и разрозненными системами, которые могут находиться вне вашего контроля. Поддерживает большое количество алгоритмов хеширования. И поддерживается 5.3.2+

function register($username, $password) {
    $lib = new PasswordLib\PasswordLib();
    $hash = $lib->createPasswordHash($password, '$2y

Рекомендации:

Исходный код / ​​Документация:GitHubPHPASS

Это слой, который поддерживает bcrypt, но также поддерживает довольно сильный алгоритм, который полезен, если у вас нет доступа к PHP> = 5.3.2 ... На самом деле он поддерживает PHP 3.0+ (хотя и не с bcrypt).

function register($username, $password) {
    $phpass = new PasswordHash(12, false);
    $hash = $phpass->HashPassword($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $phpass = new PasswordHash(12, false);
    if ($phpass->CheckPassword($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Ресурсы

Код:CVSwebСайт проекта:на OpenWallОбзор алгоритма <5.3.0:на StackOverflow

Примечание: Не используйте альтернативы PHPASS, которые не размещены на openwall, это разные проекты !!!

О компании BCrypt

Если вы заметили, каждая из этих библиотек возвращает одну строку. Это из-за того, как BCrypt работает внутри. И есть тонна ответов об этом. Вот подборка, которую я написал, которую я не буду здесь копировать / вставлять, но буду ссылаться на:

Принципиальная разница между алгоритмами хеширования и шифрования - Объяснение терминологии и некоторая базовая информация о них.Об обращении хэшей без радужных таблиц - В основном, почему мы должны использовать bcrypt в первую очередь ...Хранение bcrypt хэшей - в основном, почему соль и алгоритм включены в результат хеширования.Как обновить стоимость хэшей bcrypt - в основном, как выбрать, а затем поддерживать стоимость хеша bcrypt.Как хешировать длинные пароли с помощью bcrypt объяснение ограничения пароля в 72 символа bcrypt.Как bcrypt использует солиЛучшие практики посола и перца - В основном, не используйте «перец»Миграция старогоmd5 пароли к bcryptЗаворачивать

Есть много разных вариантов. Что вы выбираете, зависит от вас. Тем не менее, я быОЧЕНЬ рекомендуем вам использовать одну из перечисленных выше библиотек для обработки этого для вас.

Опять же, если вы используетеcrypt() напрямую, вы, вероятно, делаете что-то не так. Если ваш код используетhash() (или жеmd5() или жеsha1()), вы почти наверняка делаете что-то не так.

Просто используйте библиотеку ...

, array('cost' => 12)); save($user, $hash); } function login($username, $password) { $hash = loadHashByUsername($username); $lib = new PasswordLib\PasswordLib(); if ($lib->verifyPasswordHash($password, $hash)) { //login } else { // failure } }

Рекомендации:

Исходный код / ​​Документация:GitHubPHPASS

Это слой, который поддерживает bcrypt, но также поддерживает довольно сильный алгоритм, который полезен, если у вас нет доступа к PHP> = 5.3.2 ... На самом деле он поддерживает PHP 3.0+ (хотя и не с bcrypt).

function register($username, $password) {
    $phpass = new PasswordHash(12, false);
    $hash = $phpass->HashPassword($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $phpass = new PasswordHash(12, false);
    if ($phpass->CheckPassword($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Ресурсы

Код:CVSwebСайт проекта:на OpenWallОбзор алгоритма <5.3.0:на StackOverflow

Примечание: Не используйте альтернативы PHPASS, которые не размещены на openwall, это разные проекты !!!

О компании BCrypt

Если вы заметили, каждая из этих библиотек возвращает одну строку. Это из-за того, как BCrypt работает внутри. И есть тонна ответов об этом. Вот подборка, которую я написал, которую я не буду здесь копировать / вставлять, но буду ссылаться на:

Принципиальная разница между алгоритмами хеширования и шифрования - Объяснение терминологии и некоторая базовая информация о них.Об обращении хэшей без радужных таблиц - В основном, почему мы должны использовать bcrypt в первую очередь ...Хранение bcrypt хэшей - в основном, почему соль и алгоритм включены в результат хеширования.Как обновить стоимость хэшей bcrypt - в основном, как выбрать, а затем поддерживать стоимость хеша bcrypt.Как хешировать длинные пароли с помощью bcrypt объяснение ограничения пароля в 72 символа bcrypt.Как bcrypt использует солиЛучшие практики посола и перца - В основном, не используйте «перец»Миграция старогоmd5 пароли к bcryptЗаворачивать

Есть много разных вариантов. Что вы выбираете, зависит от вас. Тем не менее, я быОЧЕНЬ рекомендуем вам использовать одну из перечисленных выше библиотек для обработки этого для вас.

Опять же, если вы используетеcrypt() напрямую, вы, вероятно, делаете что-то не так. Если ваш код используетhash() (или жеmd5() или жеsha1()), вы почти наверняка делаете что-то не так.

Просто используйте библиотеку ...

 Lizardx09 дек. 2015 г., 00:23
ircmaxell, большое спасибо за библиотеку password_compat для 5.3.xx, раньше она нам не нужна, но сейчас мы делаем это на php-сервере 5.3.xx, и спасибо за четкий совет не пытаться делать эту логику себя.
 ircmaxell24 июн. 2013 г., 01:28
@AndrewMoore: абсолютно. Не спорю, что. Только тоmt_rand а такжеuniqid (и поэтомуlcg_value а такжеrand) не первый выбор ...
 Andrew Moore21 июн. 2013 г., 16:00
Соль должна генерироваться случайным образом, однако она не должна поступать из безопасного случайного источника.Соль не секрет, Возможность угадать следующую соль не оказывает реального влияния на безопасность; пока они поступают из достаточно большого пула данных, чтобы генерировать различные соли для каждого закодированного пароля, у вас все в порядке. Помните, что соль предотвращает использование радужных таблиц, если ваши хеши попадают в плохие руки. Они не секреты.
 Andrew Moore23 июн. 2013 г., 03:08
@ircmaxell: «достаточно большой пул данных». Однако ваш источник не обязательно должен быть ОЧЕНЬ ВЫСОКИМ источником энтропии, достаточно высоким для 128 бит. Однако, если вы исчерпали все доступные источники (у вас нет OpenSSL и т. Д.), И ваш единственный запасной вариант - mt_rand (), он все равно лучше альтернативы (то есть rand ()).
 ircmaxell21 июн. 2013 г., 16:09
@AndrewMoore абсолютно правильно! Однако соль должна обладать достаточной энтропией, чтобы быть статистически уникальной. Не только в вашем приложении, но и во всех приложениях. Такmt_rand() имеет достаточно высокий период, но начальное значение составляет всего 32 бита. Итак, используяmt_rand() эффективно ограничивает вас только 32 битами энтропии. Что благодаря проблеме «День рождения» означает, что у вас есть 50% -ная вероятность столкновения только при 7 кг сгенерированных солей (глобально). посколькуbcrypt принимает 128 битов соли, лучше использовать источник, который может предоставить все 128 битов ;-). (при 128 битах вероятность столкновения составляет 50% при хеше 2e19) ...

crypt() функция и передача в соответствующую соль Blowfish. Наиболее важным из всего уравнения является то, что A) алгоритм не был скомпрометирован и B)вы правильно солите каждый пароль, Не используйте соль для всего применения; это открывает все ваше приложение для атаки из одного набора таблиц Rainbow.

PHP - функция Crypt

 Paŭlo Ebermann09 сент. 2011 г., 16:46
На самом деле, один SHA-1 (или MD5) пароля по-прежнему легко переборчив, с солью или без соли (соль помогает против радужных таблиц, а не против перебора). Используйте bcrypt.
 CodesInChaos22 июн. 2013 г., 18:49
@Panique Почему? Алгоритм называетсяBcrypt. crypt предоставляет несколько хэшей паролей, причем bcrypt соответствуетCRYPT_BLOWFISH постоянная. Bcrypt в настоящее время самый сильный алгоритм, поддерживаемыйcrypt и некоторые другие, которые он поддерживает, довольно слабы.
 Sliq11 мая 2013 г., 22:28
Меня беспокоит, что все говорят «bcrypt», когда имеют в виду php's crypt ().
 Pieter Ennes07 июл. 2011 г., 14:03
У SHA действительно есть также параметр стоимости, с помощью опции «раундов». Когда я использую это, я также не вижу причин отдавать предпочтение bcrypt.
 caf27 янв. 2011 г., 06:41
Это правильный подход - используйте PHPcrypt() функция, которая поддерживает несколько различных функций хеширования паролей. Убедитесь, что вы не используетеCRYPT_STD_DES или жеCRYPT_EXT_DES - подойдет любой из других поддерживаемых типов (включая bcrypt под именемCRYPT_BLOWFISH).

2013.01.15 - Если ваш сервер будет поддерживать его, используйтерешение Мартинстоэкли вместо.

Каждый хочет сделать это более сложным, чем оно есть. Функция crypt () выполняет большую часть работы.

function blowfishCrypt($password,$cost)
{
    $chars='./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $salt=sprintf('$2y$%02d

Пример:

$hash=blowfishCrypt('password',10); //This creates the hash
$hash=blowfishCrypt('password',12); //This creates a more secure hash
if(crypt('password',$hash)==$hash){ /*ok*/ } //This checks a password

Я знаю, что это должно быть очевидно, но, пожалуйста, не используйте «пароль» в качестве пароля.

,$cost); //For PHP < PHP 5.3.7 use this instead // $salt=sprintf('$2a$%02d

Пример:

$hash=blowfishCrypt('password',10); //This creates the hash
$hash=blowfishCrypt('password',12); //This creates a more secure hash
if(crypt('password',$hash)==$hash){ /*ok*/ } //This checks a password

Я знаю, что это должно быть очевидно, но, пожалуйста, не используйте «пароль» в качестве пароля.

,$cost); //Create a 22 character salt -edit- 2013.01.15 - replaced rand with mt_rand mt_srand(); for($i=0;$i<22;$i++) $salt.=$chars[mt_rand(0,63)]; return crypt($password,$salt); }

Пример:

$hash=blowfishCrypt('password',10); //This creates the hash
$hash=blowfishCrypt('password',12); //This creates a more secure hash
if(crypt('password',$hash)==$hash){ /*ok*/ } //This checks a password

Я знаю, что это должно быть очевидно, но, пожалуйста, не используйте «пароль» в качестве пароля.

 martinstoeckli12 янв. 2013 г., 11:24
@JonHulka - посмотрите на PHPпакет совместимости [Строка 127], это простая реализация.
 Jon Hulka11 янв. 2013 г., 03:04
Я более подробно рассмотрю mcrypt_create_iv (), когда у меня появится момент, если ничего другого не должно немного улучшить производительность.
 CodesInChaos10 янв. 2013 г., 22:00
использованиеmcrypt_create_iv($size, MCRYPT_DEV_URANDOM) как источник соли.
 CodesInChaos12 янв. 2013 г., 09:22
Добавить кодировку Base64 и перевести на пользовательский алфавитbcrypt использует.mcrypt_create_iv(17, MCRYPT_DEV_URANDOM), str_replace('+', '.', base64_encode($rawSalt)), $salt = substr($salt, 0, 22);
 martinstoeckli10 янв. 2013 г., 15:45
Создание соли может быть улучшено (используйте случайный источник ОС), в противном случае это выглядит хорошо для меня. Для более новых версий PHP лучше использовать2y вместо2a.
Решение Вопроса

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

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

Как использовать bcrypt:Использование PHP> = 5.5-DEV

Функции хеширования паролятеперь встроены непосредственно в PHP> = 5.5, Теперь вы можете использоватьpassword_hash() создатьbcrypt хеш любого пароля:

<?php
// Usage 1:
echo password_hash('rasmuslerdorf', PASSWORD_DEFAULT)."\n";
// [email protected] - на этой странице даже не упоминается bcrypt, а тем более объяснитьxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// For example:
// [email protected] - на этой странице даже не упоминается bcrypt, а тем более объяснить.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

// Usage 2:
$options = [
  'cost' => 11
];
echo password_hash('rasmuslerdorf', PASSWORD_BCRYPT, $options)."\n";
// $2yчто это6DP.V0nO7YI3iSki4qog6OQI5eiO6Jnjsqg7vdnb.JgGIsxniOn4C

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

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
Используя PHP> = 5.3.7, <5.5-DEV (также RedHat PHP> = 5.3.3)

Существуетбиблиотека совместимости наGitHub создан на основе исходного кода вышеуказанных функций, изначально написанных на C, что обеспечивает те же функциональные возможности. Как только библиотека совместимости установлена, ее использование такое же, как указано выше (за исключением сокращенной записи массива, если вы все еще находитесь в ветке 5.3.x).

Использование PHP <5.3.7(Устаревшее)

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

class Bcrypt{
  private $rounds;

  public function __construct($rounds = 12) {
    if (CRYPT_BLOWFISH != 1) {
      throw new Exception("bcrypt not supported in this installation. See http://php.net/crypt");
    }

    $this->rounds = $rounds;
  }

  public function hash($input){
    $hash = crypt($input, $this->getSalt());

    if (strlen($hash) > 13)
      return $hash;

    return false;
  }

  public function verify($input, $existingHash){
    $hash = crypt($input, $existingHash);

    return $hash === $existingHash;
  }

  private function getSalt(){
    $salt = sprintf('$2a$%02d

Вы можете использовать этот код следующим образом:

$bcrypt = new Bcrypt(15);

$hash = $bcrypt->hash('password');
$isGood = $bcrypt->verify('password', $hash);

Кроме того, вы также можете использоватьPortable PHP Hashing Framework.

, $this->rounds); $bytes = $this->getRandomBytes(16); $salt .= $this->encodeBytes($bytes); return $salt; } private $randomState; private function getRandomBytes($count){ $bytes = ''; if (function_exists('openssl_random_pseudo_bytes') && (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // OpenSSL is slow on Windows $bytes = openssl_random_pseudo_bytes($count); } if ($bytes === '' && is_readable('/dev/urandom') && ($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) { $bytes = fread($hRand, $count); fclose($hRand); } if (strlen($bytes) < $count) { $bytes = ''; if ($this->randomState === null) { $this->randomState = microtime(); if (function_exists('getmypid')) { $this->randomState .= getmypid(); } } for ($i = 0; $i < $count; $i += 16) { $this->randomState = md5(microtime() . $this->randomState); if (PHP_VERSION >= '5') { $bytes .= md5($this->randomState, true); } else { $bytes .= pack('H*', md5($this->randomState)); } } $bytes = substr($bytes, 0, $count); } return $bytes; } private function encodeBytes($input){ // The following is code from the PHP Password Hashing Framework $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; $output = ''; $i = 0; do { $c1 = ord($input[$i++]); $output .= $itoa64[$c1 >> 2]; $c1 = ($c1 & 0x03) << 4; if ($i >= 16) { $output .= $itoa64[$c1]; break; } $c2 = ord($input[$i++]); $c1 |= $c2 >> 4; $output .= $itoa64[$c1]; $c1 = ($c2 & 0x0f) << 2; $c2 = ord($input[$i++]); $c1 |= $c2 >> 6; $output .= $itoa64[$c1]; $output .= $itoa64[$c2 & 0x3f]; } while (true); return $output; } }

Вы можете использовать этот код следующим образом:

$bcrypt = new Bcrypt(15);

$hash = $bcrypt->hash('password');
$isGood = $bcrypt->verify('password', $hash);

Кроме того, вы также можете использоватьPortable PHP Hashing Framework.

 Andrew Moore12 авг. 2011 г., 06:01
@Mike: Давай, это именно по этой причине!
 jwinn21 авг. 2011 г., 11:18
Для тех, кто думает, что им нужно изменить начало строки $ salt в функции getSalt, в этом нет необходимости. $ 2a $ __ является частью соли CRYPT_BLOWFISH. Из документов: «Blowfish хэширует с солью следующим образом:« $ 2a $ », двухзначный параметр стоимости,« $ »и 22 цифры из алфавита».
 DaveRandom19 дек. 2012 г., 15:48
Обратите внимание, что этот ответ, хотя и хороший, начинает показывать свой возраст. Этот код (как и любая реализация PHP, опирающаяся наcrypt()) подвержена уязвимости безопасности до 5.3.7 и (очень незначительно) неэффективна после 5.3.7 - подробности соответствующей проблемы можно найтиВот, Обратите также внимание, что новыйAPI хеширования паролей (обратная совместная библиотека) теперь является предпочтительным методом реализации хеширования паролей bcrypt в вашем приложении.
 Andrew Moore08 июл. 2011 г., 17:45
@ Злая Блоха: Извините, что разочаровал вас, ноmt_rand() также отображается с использованием текущего времени и текущего идентификатора процесса. Посмотри пожалуйстаGENERATE_SEED() в/ext/standard/php_rand.h.
 Andrew Moore04 авг. 2012 г., 19:03
@MichaelLang: хорошая вещьcrypt() затем проверяется и проверяется. Код выше вызывает PHPcrypt(), который вызывает POSIXcrypt() функция. Весь код, приведенный выше, генерирует случайную соль (которая не должна быть криптографически безопасной, соль не считается секретной) перед вызовомcrypt(). Может быть, вам следует провести небольшое исследование, прежде чем вызывать волка.

специально разработанный Colin Percival для bcrypt вего бумага, СуществуетPHP-расширение scrypt в PECL, В идеале этот алгоритм должен быть свернут в PHP, чтобы его можно было указать для функций password_ * (в идеале как «PASSWORD_SCRYPT»), но его пока нет.

ЗаOAuth 2 пароли:

$bcrypt = new \Zend\Crypt\Password\Bcrypt;
$bcrypt->create("youpasswordhere", 10)

Ваш ответ на вопрос