retro3fretro3f blog

Криптография для самых маленьких: шифрование с примерами на Python

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

Википедия гласит:

Криптогра́фия (от др.-греч. κρυπτός — скрытый и γράφω — пишу) — наука о методах обеспечения конфиденциальности (невозможности прочтения информации посторонним), целостности данных (невозможности незаметного изменения информации), аутентификации (проверки подлинности авторства или иных свойств объекта), а также невозможности отказа от авторства.

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

Симметричное шифрование

Предположим, что сторона А хочет передать стороне Б секретную информацию. Стоп. А, Б — это всё некрасиво и неудобно. Именно поэтому в криптографии принято называть стороны обмена информацией именами Алиса (Alice) и Боб (Bob).

Итак, как Алиса может передать сообщение, чтобы никто, кроме Боба, не смог прочесть его? Необходимо как-то изменить эти данные по заранее согласованному с Бобом алгоритму. Простейшим способом реализации такой задачи является подстановочный шифр — алгоритм, при котором каждая буква сообщения заменяется на другую букву. Например, вместо первой буквы алфавита («А») Боб c Алисой будут использовать третью («В»), вместо второй («Б») — четвертую («Г») и так далее.

В этом случае алгоритмом шифрования является сдвиг букв алфавита, а ключом — цифра 2 (сдвиг на две позиции). Любой, кто знает алгоритм и ключ, сможет расшифровать сообщение Алисы. Кстати, попробуйте и вы расшифровать это сообщение — стретвоокуф. Вам поможет простой пример на Python 3:

# -*- coding: utf-8 -*-

ALPHA = u'абвгдеёжзийклмнопрстуфхцчшщьъэюя'
 
def encode(text, step):
    return text.translate(
        str.maketrans(ALPHA, ALPHA[step:] + ALPHA[:step]))
 
def decode(text, step):
    return text.translate(
        str.maketrans(ALPHA[step:] + ALPHA[:step], ALPHA))

Такие алгоритмы шифрования, при которых Алиса и Боб должны заранее придумать и согласовать одинаковый секрет, называются симметричными, а рассмотренный пример является самым простым алгоритмом этой группы и называется шифром Цезаря. Он считается небезопасным, и его не рекомендуется использовать. Наиболее популярными и достаточно криптостойкими симметричными алгоритмами являются 3DES и AES.

Асимметричное шифрование

Но что же делать, если Алиса и Боб находятся далеко друг от друга и не могут договориться об использовании одинакового секрета, поскольку есть некая Ева (от англ. eavesdropper — подслушивающий), которая так и хочет узнать тайны Алисы и Боба? В этом случае Боб может отправить Алисе замок, ключ от которого есть только у него. Алиса положит письмо в коробку и запрёт её на этот замок. Теперь ни Алиса, ни Ева не смогут открыть коробку и прочесть письмо.

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

Наиболее популярным алгоритмом шифрования с открытым ключом является RSA. Вот как выглядит его реализация на языке Python с использованием библиотеки RSA:

	# -*- coding: utf-8 -*-
	  
	import rsa

	#Боб формирует публичный и секретный ключ

	(bob_pub, bob_priv) = rsa.newkeys(512)

	#Алиса формирует сообщение Бобу и кодирует его в UTF8, 
	#поскольку RSA работает только с байтами
	message = 'hello Bob!'.encode('utf8')

	#Алиса шифрует сообщение публичным ключом Боба
	crypto = rsa.encrypt(message, bob_pub)

	#Боб расшифровывает сообщение своим секретным ключом
	message = rsa.decrypt(crypto, bob_priv)
	print(message.decode('utf8'))

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