Найти тему

О шифровании простым языком

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

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

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

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

Например, сложение: 3+8. Если мы выполним эту операцию, мы получим 11. А вот после того, как мы провели операцию сложения, мы уже не знаем, какие два числа были сложены, чтобы получить 11. Это может быть и 5+6, и 4+7, и 9+2

Для расшифровки в нашем случае нужно знать хотя бы одно слагаемое — мы сразу сможем получить второе. Алгоритм расшифровки такой: x=y-z, где x — результат выполнения функции, а y — слагаемое, которое нам известно. Если рассмотреть это по-другому, x — данные в зашифрованном виде, y — ключ шифрования, z — исходные данные.

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

Если вернуться к нашему примеру 3+8=11, 3 — входные данные, 8 — ключ шифрования, 11 — зашифрованные данные. Чтобы расшифровать (получить) исходные данные, нам нужно провести операцию дешифровки: x=11-8. Мы получаем исходные данные — 3. Если не знать ключ шифрования (8), придётся перебирать все возможные данные: 11-0, 11-1, 11-2, 11-3 и так далее.

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

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

Например, популярный алгоритм шифрования RSA устроен так:

Генерация ключей RSA:

  • Выбираются два простых числа. Запишем их как q и p;
  • Эти числа перемножаются, а результат записывается. Пусть это будет n;
  • вычисляется значение функции Эйлера по формуле: (q-1) * (p-1). Запишем это как f;
  • Вот здесь сложно. Нам нужно придумать такое число, которое больше единицы, меньше того, что мы получили в третьем пункте и при этом быть с ним взаимно простым. Можно взять 3, 7, 17, 257 или любое другое (если оно соответствует условиям и меньше того, что у вас получилось в третьем пункте. Это число является открытой экспонентой, запишем как e;
  • Вычисляем секретную экспоненту. Берём формулу d = (f*k+1)/e. Число k мы должны подобрать сами. Подбираем до тех пор, пока d не станет целым числом.
  • В итоге пара (e, n) — открытый ключ; (d, n) — закрытый ключ

Шифрование RSA:

Предположим, исходные данные (число), это m. Причём оно не может быть больше, чем n (см. генерацию ключей чуть выше). Чтобы зашифровать m, мы m возводим в степень e (из открытого ключа) и находим остаток от деления на n (открытого ключа)

Расшифровка RSA:

Предположим, зашифрованные данные (число), это c. Тогда мы c возводим в степень d и находим остаток от деления на n (закрытого ключа).

Конечно на практике применяются куда более большие числа. Например в качестве q и p генерируются числа длиной в 2048 бит. А это, между прочим, числа примерно вот такие: 32317006071311007300714876688669951960444102669715484032130345427524655138867890893197201411522913463688717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384067568276792218642619756161838094338476170470581645852036305042887575891541065808607552399123930385521914333389668342420684974786564569494856176035326322058077805659331026192708460314150258592864177116725943603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656697935045997268352998638215525166389437335543602135433229604645318478604952148193555853611059596230656. Если перемножить два подобных числа, то потом найти один из множетелей даже методом перебора уже тяжеловато.

Т.к. вся информация в компьютерах представлена в виде бит (чисел 0 и 1), в том числе текст, изображения, музыка, видео и т.д., становится не трудно подмешать сюда математику. Абсолютно любую информацию в компьютере можно представить в последовательности чисел и, разумеется, можно делать с ними что угодно.

Давайте теперь попробуем пошифровать так, как это делается на реальной практике. Для этого будем пользоваться инструментарием PGP. Эта штука умеет намного больше, чем шифровать по RSA, но сейчас нас интересует только RSA-шифрование.

Здесь для шифрования будем использовать Linux-систему; потребуется установленный пакет gpg в системе.

Для генерации ключей мы выполним команду gpg —full-generate-key. Команда задаст несколько вопросов. Необходимо на них ответить самостоятельно. Если вы не знаете как отвечать, значит вам эта статья не понятна. Для публичного ключа потребуется указать Имя, Фамилию и почту. Эта информация абсолютно никуда не отправляется и создаётся только для удобства обращения к ключу. Можно ввести любую информацию. После генерации, ключи будут сохранены в системе. При необходимости их можно будет экспортировать.

Ключи шифрования могут храниться либо в бинарном виде, либо в текстовом виде. В текстовом виде они выглядят примерно так:

-2

Теперь мы запишем секретную информацию в текстовый файл. Чтобы зашифровать файл, выполним команду gpg -ae secret.txt, где a — означает armored (мы хотим, чтобы зашифрованный вид файла был всё ещё текстовым, а не бинарным), а e — означат encrypt. Утилита спросит каким ключом шифровать, можете просто указать email, который вы указали при генерации ключа.

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

Для расшифровки файла нужно выполнить команду: gpg secret.txt.asc.

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

Команда для экспорта публичного ключа:
gpg —export <email ключа> -o public.key

Команда для импорта публичного ключа:
gpg —import public.key

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