Хеширование с использованием SHA-256 в криптографии

LinuxBeginner
Практиковаться сейчас

Введение

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

Криптографическая хеш-функция — это математический алгоритм, который принимает на вход сообщение (или 'message') любого размера и возвращает строку байтов фиксированного размера. Этот результат обычно называется 'дайджест' (digest) или 'хеш' (hash). Например, SHA-256 всегда генерирует 256-битный (32-байтовый) хеш.

Эти функции обладают несколькими важными свойствами:

  • Детерминированность: Один и тот же вход всегда будет давать один и тот же выход.
  • Однонаправленность: Вычислительно невозможно обратить функцию и найти исходный ввод по его хешу.
  • Лавинный эффект (Avalanche Effect): Небольшое изменение во вводе (например, изменение одного символа) приведет к кардинально другому хешу на выходе.

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

Свойства хеш-функции

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

Сначала сгенерируем SHA-256 хеш для строки "hello". Мы будем использовать команду echo для передачи строки в openssl.

echo -n "hello" | openssl dgst -sha256

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

Вы должны увидеть вывод, похожий на этот:

SHA2-256(stdin)= 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

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

echo -n "hello" | openssl dgst -sha256

Обратите внимание, что вывод идентичен. Это подтверждает, что для одного и того же ввода хеш SHA-256 всегда одинаков.

SHA2-256(stdin)= 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Далее продемонстрируем лавинный эффект. Мы внесем очень небольшое изменение в нашу входную строку — заменим "hello" на "Hello" (с заглавной 'H').

echo -n "Hello" | openssl dgst -sha256

Посмотрите на новый хеш:

SHA2-256(stdin)= 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

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

Вычисление хеша файла

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

Скрипт настройки для этой лабораторной работы уже создал файл с именем message.txt в вашей текущей директории (~/project). Сначала давайте посмотрим его содержимое с помощью команды cat.

cat message.txt

Вы увидите следующее содержимое:

This is a secret message.

Теперь вычислим SHA-256 хеш этого файла. Синтаксис похож на тот, что вы использовали ранее, но вместо передачи ввода через pipe (конвейер), вы передаете имя файла в качестве аргумента команде openssl dgst.

openssl dgst -sha256 message.txt

Команда обработает файл и выведет его SHA-256 хеш. Вывод будет выглядеть следующим образом:

SHA2-256(message.txt)= 6432f513cfd40d47c8584494c0524468257e50dc1a0422f73becac85189543f8

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

Генерация нескольких хешей

На этом шаге вы получите больше практики в генерации SHA-256 хешей для различных строковых вводов. Это поможет закрепить ваше понимание того, как любой уникальный ввод производит уникальный хеш. Мы продолжим использовать команду echo -n, перенаправляемую в openssl, чтобы гарантировать, что мы хешируем только саму строку, без каких-либо дополнительных символов.

Сначала сгенерируем хеш для строки "labex".

echo -n "labex" | openssl dgst -sha256

Вывод будет SHA-256 хешем для "labex":

SHA2-256(stdin)= 679e75b679886c5eaf8aaab88ddfc0181e6dae14cff346db8ba398bd7b2e31fe

Далее попробуем другую строку, "crypto", чтобы увидеть ее уникальный хеш.

echo -n "crypto" | openssl dgst -sha256

Как и ожидалось, это дает совершенно другой хеш:

SHA2-256(stdin)= da2f073e06f78938166f247273729dfe465bf7e46105c13ce7cc651047bf0ca4

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

Демонстрация устойчивости к коллизиям

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

Сначала пересчитаем хеш исходного файла message.txt, чтобы освежить его в памяти.

openssl dgst -sha256 message.txt

Вы снова должны увидеть исходный хеш:

SHA2-256(message.txt)= 6432f513cfd40d47c8584494c0524468257e50dc1a0422f73becac85189543f8

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

echo "." >> message.txt

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

cat message.txt

Вы увидите точку в конце:

This is a secret message.
.

Теперь повторно хешируем измененный файл.

openssl dgst -sha256 message.txt

Новый хеш будет следующим:

SHA2-256(message.txt)= 4106e1c985a4ee1754fff76b8bffda0c4844679885cb70758f24cd43e771daac

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

Создание хеша пароля

На этом шаге вы отойдете от командной строки и напишете простой скрипт на Python для хеширования пароля. Хранение паролей в открытом виде является серьезной уязвимостью безопасности. Стандартная практика — хранить хеш пароля. Когда пользователь пытается войти в систему, система хеширует введенный им пароль и сравнивает его с сохраненным хешем.

Установочный скрипт уже создал пустой файл с именем hash_password.py. Теперь вы добавите в него код с помощью текстового редактора nano.

Откройте файл с помощью nano:

nano hash_password.py

Теперь скопируйте и вставьте следующий код на Python в редактор nano:

import hashlib

## Пароль, который мы хотим хешировать
password = "mysecretpassword"

## Хеш-функции в Python работают с байтами, а не со строками.
## Сначала мы должны закодировать строку в байты, используя UTF-8.
password_bytes = password.encode('utf-8')

## Создаем новый объект хеша SHA-256.
sha256_hash = hashlib.sha256(password_bytes)

## Получаем шестнадцатеричное представление хеша.
hex_digest = sha256_hash.hexdigest()

print(f"The password is: {password}")
print(f"The SHA-256 hash is: {hex_digest}")

Этот скрипт выполняет следующее:

  1. Импортирует библиотеку hashlib, которая предоставляет различные алгоритмы хеширования.
  2. Определяет строковое значение пароля.
  3. Кодирует строку в байты с помощью .encode('utf-8'). Это критически важный шаг, поскольку хеш-функции работают с байтами.
  4. Создает объект хеша SHA-256 и обновляет его байтами пароля.
  5. Получает итоговый хеш в удобочитаемом шестнадцатеричном формате с помощью .hexdigest().

После вставки кода сохраните файл и выйдите из nano, нажав Ctrl+X, затем Y и затем Enter.

Наконец, запустите ваш скрипт Python из терминала:

python3 hash_password.py

Скрипт выполнится и выведет пароль и соответствующий ему хеш SHA-256:

The password is: mysecretpassword
The SHA-256 hash is: 94aefb8be78b2b7c344d11d1ba8a79ef087eceb19150881f69460b8772753263

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

Резюме

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

В этой лабораторной работе вы узнали:

  • Основные свойства хеш-функций: они детерминированы, однонаправленны и демонстрируют лавинный эффект.
  • Как использовать команду openssl dgst -sha256 в среде Linux для вычисления хешей как для строк, так и для файлов.
  • Важность хеширования для проверки целостности файлов и обнаружения подделки.
  • Как использовать библиотеку Python hashlib для программной генерации хешей SHA-256, что является распространенной задачей в обеспечении безопасности паролей.

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