Что такое хэш пароля. Хэширование паролей с помощью Hash API. Понятие хэш-функции пароля

  • бесплатность доступа
  • размер словаря
  • поддерживаемые типы хэшей
  • наличие детального криптоанализа (например с помощью Rainbow-таблиц)
    Обновлено 29.03.2013
  1. cmd5.ru

    cmd5.ru один из старейших сервисов для расшифровки хэшей, существует с 2006 года. Преимущества сервиса:

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

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

    типы хэшей:

    • md5(md5($pass))
    • sha256
    • mysql
    • mysql5
    • md5($pass.$salt);Joomla
    • md5($salt.$pass);osCommerce
    • md5(md5($pass).$salt);Vbulletin;IceBB;Discuz
    • md5(md5($salt).$pass)
    • md5($salt.$pass.$salt);TBDev
    • md5($salt.md5($pass))
    • md5(md5($pass).md5($salt))
    • md5(md5($salt).md5($pass));ipb;mybb
    • sha1($salt.$pass)
    • sha1(lower($username).$pass);SMF
    • sha1(upper($username).’:’.upper($pass));ManGOS
    • sha1($username.’:’.$pass)
    • sha1(salt.pass.’UltimateArena’)
    • MD5(Unix);phpBB3;WordPress
    • Des(unix)
    • mssql
    • md5(unicode)
    • serv-u
    • radmin v2.x
  2. c0llision.net
    free | 295G | md5 md5(md5()) ntlm lm pwdump | distributed network

    c0llision.net – отличный бесплатный сервис, основанный на большой сети по распределенному перебору md5, lm и ntlm хешей. Проект бурно развивается, что не может не радовать. Для добавления хешей в очередь предпочтительней использовать IRC, хотя и имеется веб-интерфейс.

  3. crackstation.net
    free | 190G | LM NTLM md2 md4 md5 md5(md5) md5-half sha1 sha1(sha1_bin()) sha224 sha256 sha384 sha512 ripeMD160 whirlpool MySQL 4.1+ | dic

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

  4. md5.darkbyte.ru
    free | 329M + 48G | md5 | dic

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

  5. tmto.org
    free | 36G | md5 lm ntlm sha1 | rainbow tables

    После продолжительного оффлайна проект TMTO (Time-Memory Trade Off Cracking) вновь стал доступен. База стала еще больше, появились новые алгоритмы, сервис остался бесплатным, как и прежде. Радует высокая скорость расшифровки благодаря постоянному росту кластера. За один раз можно отправить неограниченное количество хэшей для расшифровки.

  6. hashcracking.ru
    free & auth | 3M | md5 mysql mysql5 sha1 | dic rainbow tables

    hashcracking.ru по-прежнему в строю, позволяет проводить поиск mysql и mysql5 паролей, брутить по маске, есть возможность перебора по словарю с указанием salt.

  7. www.md5decrypter.co.uk
    free | 8,7G | md5 | dic

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

На данный момент использование bcrypt - это лучший способ хэширования паролей, однако множество разработчиков по старинке используют MD5 и SHA1. Многие из них, не применяют технику добавления соли. В PHP 5.5 решили акцентировать внимание разработчиков на алгоритме bcrypt и создали специальный хэш API.

Хэш API состоит из следующих функций:

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

password_hash()

Использование функции crypt() у многих вызывает ступор из-за сложности, поэтому вместо неё применяются упрощённые способы создания хэша. К примеру:

$hash = md5($password . $salt); // работает, но не надёжно

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

$hash = password_hash($passwod, PASSWORD_DEFAULT);

Вот и всё! Первый параметр - это строка представляющая собой пароль; второй - алгоритм, который будет применён.

Алгоритм, который используется по умолчанию - bcrypt, но в будущем будут добавлены и другие, более продвинутые алгоритмы. Если вы используете PASSWORD_DEFAULT, то знайте, что на выходе получите строку из более 60 символов. Она может быть и больше, особенно, при использовании других алгоритмов, так что в таблице размер поля можете выставить 255. В качестве второго параметра, вы можете использовать константу PASSWORD_BCRYPT. В этом случае, размер строки на выходе будет ровно 60 символов.

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

$options = [ "salt" => custom_function_for_salt(), //напишите свою функцию генерации соли "cost" => 12 // по умолчанию равен 10 ]; $hash = password_hash($password, PASSWORD_DEFAULT, $options);

Вот и всё!

password_verify()

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

Функция password_verify() принимает пароль в обычном виде и его хэш. В зависимости от результатов проверки, возвращает true или false.

If (password_verify($password, $hash)) { // Успех! } else { // Провал }

Заметьте, что соль находится в самом хэше, так что нам не нужно указывать её вручную.

password_needs_rehash()

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

If (password_needs_rehash($hash, PASSWORD_DEFAULT, ["cost" => 12])) { // необходимо создать хэш пароля ещё раз $hash = password_hash($password, PASSWORD_DEFAULT, ["cost" => 12]); }

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

password_get_info()

password_get_info() возвращает параметры хэширования:

  • algo - константа с названием алгоритма
  • algoName - название алгоритма
  • options - различные настройки

Заключение

Новый API для хэширования паролей очень прост. Это отличная замена функции crypt(). Если вам на сервере доступна версия PHP 5.5, то мы рекомендуем воспользоваться данным API.

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

Почему я должен хешировать пароли пользователей в моем приложении?

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

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

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

Почему популярные хеширующие функции, такие как md5() и sha1() не подходят для паролей?

Такие хеширующие алгоритмы как MD5, SHA1 и SHA256 были спроектированы очень быстрыми и эффективными. При наличии современных технологий и оборудования, стало довольно просто выяснить результат этих алгоритмов методом "грубой силы" для определения оригинальных вводимых данных.

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

Если популярные хеширующие функции не подходят, как же я тогда должен хешировать свои пароли?

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

Serious Security: How to store your users’ passwords safely

In summary, here is our minimum recommendation for safe storage of your users’ passwords:

Use a strong random number generator to create a salt of 16 bytes or longer.
Feed the salt and the password into the PBKDF2 algorithm.
Use HMAC-SHA-256 as the core hash inside PBKDF2.
Perform 20,000 iterations or more. (June 2016.)
Take 32 bytes (256 bits) of output from PBKDF2 as the final password hash.
Store the iteration count, the salt and the final hash in your password database.
Increase your iteration count regularly to keep up with faster cracking tools.

Whatever you do, don’t try to knit your own password storage algorithm.

Недостатки простого хэширования

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

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

Злоумышленники могут поступить ещё проще - конкретные хэши в онлайновых БД:






Также нужно понимать, что если два и более одинаковых пароля имеют одинаковые хэши, то, взломав один хэш, мы получаем доступ ко всем аккаунтам, где используется тот же пароль. Для примера: пусть у нас несколько тысяч пользователей, наверняка несколько из них используют пароль 123456 (если настройки сайта не заставляют усложнять пароль). MD5-хэш для этого пароля. Так что если вы заполучите этот хэш и поищете в базе данных по этому значению, то найдёте всех пользователей с таким паролем.

Почему небезопасны хэши с применением соли

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

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

f(password, salt) = hash(password + salt)

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

if (hash([введённый пароль] + [соль]) == [хэш]) тогда пользователь аутентифицирован

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

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

Момент случайности

Для генерирования подходящей соли нам нужен хороший генератор случайных чисел. Сразу забудьте о функции rand().

Применение технологий шифрования

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

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

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

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

Предположим, что в таблице хранятся следующие данные в виде обычного текста:

Кто-то в Adobe решил зашифровать пароли, но при этом совершил две большие ошибки:


  1. использовал один и тот же криптоключ;

  2. оставил поля passwordHint незашифрованными.

Допустим, после шифрования таблица стала выглядеть так:

Мы не знаем, какой применялся криптоключ. Но если проанализировать данные, то можно заметить, что в строках 2 и 7 используется один и тот же пароль, так же как и в строках 3 и 6.

Пришло время обратиться к подсказке пароля. В строке 6 это «I’m one!», что совершенно неинформативно. Зато благодаря строке 3 мы можем предположить, что пароль - queen. Строки 2 и 7 по отдельности не позволяют вычислить пароль, но если проанализировать их вместе, то можно предположить, что это halloween.

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

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

Простейший вариант «настройки» - так называемый , уникальный для каждой записи в таблице. Не рекомендуется пользоваться им в жизни, здесь он показан лишь для примера:

f(key, primaryKey) = key + primaryKey

Здесь ключ и первичный ключ просто сцепляются вместе. Но для обеспечения безопасности следует применить к ним алгоритм хэширования или функцию формирования ключа (key derivation function). Также вместо первичного ключа можно для каждой записи использовать (аналог соли).

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

Конечно, нужно будет ещё что-то сделать с подсказками паролей, но всё-таки уже получилось хоть что-то адекватное.

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

PHP 5.5

Сегодня оптимальным способом хэширования паролей считается использование bcrypt. Но многие разработчики всё ещё предпочитают старые и более слабые алгоритмы вроде MD5 и SHA-1. А некоторые при хэшировании даже не пользуются солью. В PHP 5.5 был представлен новый API для хэширования, который не только поощряет применение bcrypt, но и существенно облегчает работу с ним. Давайте разберём основы использования этого нового API.

Здесь применяются четыре простые функции:


  • password_hash() - хэширование пароля;

  • password_verify() - сравнение пароля с хэшем;

  • password_needs_rehash() - перехэширование пароля;

  • password_get_info() - возвращение названия алгоритма хэширования и применявшихся в ходе хэширования опций.

password_hash()

Несмотря на высокий уровень безопасности, обеспечиваемый функцией crypt(), многие считают её слишком сложной, из-за чего программисты часто допускают ошибки. Вместо неё некоторые разработчики используют для генерирования хэшей комбинации слабых алгоритмов и слабых солей:
Функция password_hash() существенно облегчает разработчику жизнь и повышает безопасность кода. Для хэширования пароля достаточно скормить его функции, и она вернёт хэш, который можно поместить в БД:
И всё! Первый аргумент - пароль в виде строки, второй аргумент задаёт алгоритм генерирования хэша. По умолчанию используется bcrypt, но при необходимости можно добавить и более сильный алгоритм, который позволит генерировать строки большей длины. Если в своём проекте вы используете PASSWORD_DEFAULT, то удостоверьтесь, что ширина колонки для хранения хэшей не менее 60 символов. Лучше сразу задать 255 знаков. В качестве второго аргумента можно использовать PASSWORD_BCRYPT. В этом случае хэш всегда будет длиной в 60 символов.

Обратите внимание, что вам не нужно задавать значение соли или стоимостного параметра. Новый API всё сделает за вас. Поскольку соль является частью хэша, то вам не придётся хранить её отдельно. Если вам всё-таки нужно задать своё значение соли (или стоимости), то это можно сделать с помощью третьего аргумента:
custom_function_for_salt(), // Напишите собственный код генерирования соли "cost" => 12 // По умолчанию стоимость равна 10 ]; $hash = password_hash($password, PASSWORD_DEFAULT, $options);
Всё это позволит вам использовать самые свежие средства обеспечения безопасности. Если в дальнейшем в PHP появится более сильный алгоритм хэширования, то ваш код станет использовать его автоматически.

password_verify()

Теперь рассмотрим функцию сравнения пароля с хэшем. Первый вводится пользователем, а второй мы берём из БД. Пароль и хэш используются в качестве двух аргументов функции password_verify(). Если хэш соответствует паролю, то функция возвращает true.
Помните, что соль является частью хэша, поэтому она не задаётся здесь отдельно.

password_needs_rehash()

Если вы захотите повысить уровень безопасности, добавив более сильную соль или увеличив стоимостный параметр, или изменится алгоритм хэширования по умолчанию, то вы, вероятно, захотите перехэшировать все имеющиеся пароли. Данная функция поможет проверить каждый хэш на предмет того, какой алгоритм и параметры использовались при его создании:
12])) { // Пароль надо перехэшировать, поскольку использовался не текущий // алгоритм по умолчанию либо стоимостный параметр не был равен 12 $hash = password_hash($password, PASSWORD_DEFAULT, ["cost" => 12]); // Не забудьте сохранить новый хэш! }
Не забывайте, что вам нужно будет это делать в тот момент, когда пользователь пытается залогиниться, поскольку это единственный раз, когда у вас будет доступ к паролю в виде простого текста.

password_get_info()

Данная функция берёт хэш и возвращает ассоциативный массив из трёх элементов:

  • algo - константа, позволяющая идентифицировать алгоритм;

  • algoName - название использовавшегося алгоритма;

  • options - значения разных опций, применявшихся при хэшировании.

Более ранние версии PHP

Как видите, работать с новым API не в пример легче, чем с неуклюжей функцией crypt(). Если же вы используете более ранние версии PHP, то рекомендую обратить внимание на библиотеку . Она эмулирует данный API и автоматически отключается, когда вы обновляетесь до версии 5.5.

Заключение

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

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

// наш пароль
$pass="123456";
$hash=password_hash($pass, PASSWORD_DEFAULT);
?> Вот так легко и просто. Первым параметр - строка пароля, который необходимо захэшировать, а второй параметр определяет алгоритм, который должен быть использован для генерирования хэша.

Алгоритм по умолчанию, в настоящее время, BCrypt, но более сильный алгоритм может быть установлен по умолчанию, когда-нибудь в будущем, и, возможно, он будет генерировать большие строки. Если вы используете PASSWORD_DEFAULT, обязательно храните хэш в колонке, размером больше 60 символов. Лучше всего установить размер 255. Также можете использовать PASSWORD_BCRYPT в качестве второго параметра. В этом случае результат всегда будет 60 символов.

Итак, если Вам показалось этого мало, можете использовать свою собственную соль
$op=[
"salt" => gensalt(), // здесь Ваша функция генерации соли
"cost" => 12
];
$hash=password_hash($pass, PASSWORD_DEFAULT, $op);
?> Готово.

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

// $hash - это хэш пароля, полученный из базы
if (password_verify($pass, $hash)):
print "Верный пароль!";
else:
print "Неверный пароль:(";
endif;
?> password_needs_rehash()
Функция password_needs_rehash() проверяет, использует ли хэш пароля конкретный алгоритм, соль и стоимость вычисления.
if (password_needs_rehash($hash, PASSWORD_DEFAULT, ["cost" => 12])):
$hash=password_hash($pass, PASSWORD_DEFAULT, ["cost" => 12]);
endif;
?> Данную операцию можно делать при входе пользователя в систему, ведь только тогда мы получаем доступ к паролю в явном виде.

password_get_info()
Функция password_get_info() принимает хэш и возвращает ассоциативный массив из трех элементов:
. algo - константа, которая идентифицирует конкретный алгоритм
. algoName - название используемого алгоритма
. options - различные опции, используемые при генерации хэша

Понравилась статья? Поделиться с друзьями: