Какие бы криптографические вычисления вы ни делали - без хэширования обойтись, скорее всего, не получится. Электронная подпись, проверка целостности данных, сравнение двух текстов и т.д. - везде используется хэшировние, везде вычисляется хэш. И, конечно, блокчейн без хэша просто немыслим.
Попробую сегодня на пальцах рассказать, что это такое и зачем это нужно.
Этим постом открываю мини-рубрику "криптография на пальцах". Мне хотелось бы понять, нужно ли это моим читателям. Прошу вас активнее пользоваться лайками/дизлайками, чтобы дать мне обратную связь.
Хэш еще называют свёрткой, в этом очень точно описывается суть этой математической операции.
Мы все знаем, что любая информация в цифровом виде представляет собой последовательность чисел. Блок информации может быть очень большим - это может быть текст "Войны и мира", или вообще вся Санта-Барбара. А может быть очень коротким. В современном мире громадное количество блоков информации, и часто нужен какой-то простой способ уникально идентифицировать каждый блок. Или, как еще иногда говорят, получить "отпечаток текста".
В этом хэш очень похож на отпечаток пальца человека. В отпечатке пальца нет всей информации о человеке, но по отпечатку пальца человека можно уникально идентифицировать. Нечто подобное для блоков информации делает хэш-функция.
Берем огромный роман "Война и мир" и получаем от него короткий, тридцатидвухбайтный хэш (256 бит). И этот хэш (результат вычисления хэш-функции) уникально идентифицирует текст "Войны и мира".
Представим, допустим, что кто-то взял и изменил этот текст. Например, изменил одну букву где-то в середине романа. Снова вычисляем хэш от нового, измененного текста. Полученное значение будет очень сильно отличаться от прошлого. Т.е. новый текст даст другой хэш, пусть даже изменилась всего одна буква!
Вот почему эту операцию еще называют операцией свертки. Она как бы сворачивает большой блок информации до значения фиксированного размера. Причем назад развернуть, конечно же, уже не получится. Не получится из тридцатидвухбайтного значения получить многомегабайтный исходный текст.
Собственно, это главная функция хэша - получать некую уникальную числовую характеристику блока информации. И характеристика эта - фиксированного размера, не зависит от размера исходного блока информации. Вот для этого изначально хэш и придуман.
Как теперь сравнить два разных текста? А просто вычисляем хэш от каждого. Если хэши разные - то и исходные тексты разные. Даже если разница в одном символе в огромном романе. Кстати, в программировании так время от времени делают: чтобы не париться с посимвольным сравнением огромных текстов, просто сравнивают вычесленные от них хэши. Или чтобы организовать хранение данных по парам "ключ-значение", используют хэш-таблицу.
Иногда на некоторых сайтах можно увидеть интересные надписи, вроде "контрольная сумма MD5". Смысл такой: скачиваете файл, но вдруг возникает сомнение, а не подменил ли кто-то файл? Проверить это можно разными способами, один из них - вычислить контрольную сумму. Контрольная сумма, кстати - это один из способов хэширования, смысл практически тот же самый. Из большого текста получить маленькую числовую характеристику. А MD5 - это название конкретного алгоритма хэширования.
Так вот, скачиваете файл, вычисляете от него хэш MD5 (есть утилиты для этого) и сравниваете с тем, что на сайте написано. Совпадает? Все отлично! Нет? Упс... Или недокачался, или кто-то файл подменил... Кстати, антивирусы имеют базу данных, в которой для каждого системного файла есть его хэш. Если на компьютере пользователя у системного файла другой хэш - это значит, что файл поврежден и заражен. И иногда антивирус так и говорит: "не совпадают контрольные суммы системных файлов" или "не совпадают хэши файлов".
Как рассчитывают хэш? Можно придумать самый простой алгоритм вроде такого. Берем исходный блок чисел, и просто последовательно перемножаем их друг на друга. Когда число становится слишком большим (превышает размер требуемого хэша) - отрезаем лишнее. И дальше перемножаем. Снова слишком большое число? Снова отрезаем. В итоге получится какое-то число, которое и будет хэшем. Если в исходной последовательности байт (в исходном тексте) изменить одно значение - то произведение, скорее всего, изменится, и изменится (скорее всего) наше обрезаное значение. Это пример примитивной хэш-функции. На практике никто таким алгоритмом не пользуется, потому что он не стойкий к ряду неприятностей. Например, если просто поменять местами два символа рядом - произведение не изменится. А текст-то изменился!
Поэтому реальные алгоритмы хэширования включают в себя массу всяких дополнительных действий. Перемешивание бит, перемножения с разными коэффициентами и т.д. Всё для того, чтобы даже малейшее изменение исходного текста разительно меняло значение хэша. Только в криптографии говорят не "разительно", а "лавинообразно".
Вообще говоря, возможна ситуация, когда два разных текста вдруг дадут одинаковый хэш. Эта ситуация называется коллизией. И при разработке алгоритмов стремятся к тому, чтобы вероятность этого была предельно мала. Но время от времени в старых алгоритмах находят уязвимости (способ сформировать коллизию), потому и постоянно разрабатывают новые и новые алгоритмы хэширования. Только общеизвестных сейчас несколько десятков алгоритмов.
Чтобы представить себе, как вообще такое возможно - каждому тексту поставить в соответствие уникальную числовую характеристику, я в свое время придумал себе такую картинку. Допустим, каждый текст, написаный когда-либо человеком, имеет порядковый номер. Вот пусть этот поряковый номер и будет уникальной характеристикой (хэшем) текста. Если размер хэша у нас 256 бит (большинство алгроитмов генерируют хэш от 140 до 256 бит), то с помощью числа такого размера можно пронумеровать каждый электрон во вселенной! Потому что во вселенной всего 10 в степени 80 электронов, а это сопоставимо с двойкой в степени 256. Т.е. понятно, что человечесво не способно даже близко наделать столько текстов; так что для каждого из них найдется какой-нибудь отдельный номер из этого огромного количества возможных номеров. Так что это возможно - каждому тексту дать уникальный хэш.
Но как вы понимаете, из порядкового номера нельзя получить исходный текст. И это правда - при вычислении хэша информация обрезается. Поэтому, зная хэш, невозможно узнать исходный текст. Это свойство хэш-функции очень важно, и очень широко используется. Например, пароли ни в какой системе не хранятся, но хранятся их хэши. Пользователь вводит пароль - вычисляется хэш - если совпал с тем, который в базе данных - отлично, значит, пароль правильный.
И, конечно, хэш, благодаря этому свйоству необратимости, очень широко используется в блокчейне. Там очень важно именно это свойство - невозможность подобрать исходное значение, зная требования к хэшу. Думаю рассказать об этом немного подробнее в одном из следующих постов.
Подписывайтесь на канал "Технологии Денег" в Яндекс.Дзен и Телеграм! У меня много интересного материала!