Время прочтения: 9 мин.

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

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

Хэш-функции очень сильно отличаются от обычного шифрования. Зашифровав

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

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

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

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

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

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

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

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

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

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

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

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

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

Что такое «соль»? «Соль»- это строка данных которая пропускается через хэш-функции вместе с паролем.

Использование «соли» при хэшировании гарантирует то, что даже при одинаковых паролях значение хэша будет разное. Допустим, если Алиса и Боб используют одинаковый пароль qwerty. Хэш этих паролей будут кардинально отличаться из-за того, что была использована «соль».

В интернете есть огромное количество уже прочитанных заранее хэшей. Для самых популярных паролей, например, на сайте «crackstation» можно проверить, как это работает. Для начала давайте пропустим самый часто используемый пароль qwerty через хэш-функцию sha-256.

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

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

Так используются специально замедленные хэш-функции, на вычисление которых уходит больше времени, чем на вычисление стандартных функций. Это функции: decrypt, sckrypt или argon2. Их использование для хранения паролей полностью нейтрализует возможный «брутфорс» (Brute-force Attack). Такие  функции используются для создания секретного ключа, который состоит из пароля пользователя, «соли», и дополнительного параметра cost. Параметр cost  необходим для защиты от «радужных таблиц».

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

Со временем компьютеры станут мощнее и атаки полного перебора на этот алгоритм смогут быстрее достигать своей цели. Для защиты от этого необходимо просто увеличить параметр cost, который определяет количество циклов.

Чем больше циклов, тем больше времени потребуется для хеширования исходной информации.

Давайте рассмотрим метод защиты данных, который используют сервис dropbox. Изначально dropbox берёт пароль пользователя и пропускают его через определенную простую хэш-функцию без использования «соли». И затем полученный хэш пропускается через функцию BCrypt с использованием «соли» и параметр cost величиной в 10 циклов. Это защищает от брутфорса (Brute-force Attack). Так в конечном итоге вся эта информация шифруется алгоритмом шифрования aes. Злоумышленнику придется вскрывать все эти слои защиты, чтобы добраться до нужной ему информации.

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

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

чем пароль из 6 символов, но пропущенный через функцию BCrypt с параметром cost в 25 циклов.

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

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

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

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

Пример применения хэширования паролей в Python с помощью модуля BCrypt.

Модуль bcrypt в PyPi предлагает удобную реализацию BCrypt, которую мы можем установить через pip:

pip install bcrypt

После того, как установили BCrypt с помощью pip, вы можете импортировать его в свой проект:

import bcrypt 

Возьмем «Passwordnew» в качестве примера пароля, чтобы показать его в использование BCrypt:

pwd = 'Passwordnew'
bytePwd = password.encode('utf-8')

Хешируем зашифрованный пароль с помощью BCrypt:

# Generate salt
mySalt = bcrypt.gensalt()
# Hash password
hash = bcrypt.hashpw(bytePwd, mySalt)

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

print(bcrypt.checkpw(password, hash))
# Output: True

Таким образом, для наглядности мы проиллюстрировали процесс хеширования пароля на примере BCrypt.

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