
Представьте шумную городскую площадь. На ней стоят двое — Алиса и Коля. Им необходимо договориться о секретном ключе, не переходя на шепот. Проблема в том, что вокруг полно людей, а среди них — Ева, которая жадно фиксирует каждый звук. Прямое общение исключено: любая фраза, адресованная Коле, немедленно станет достоянием Евы. Казалось бы, создать общий секрет в таких условиях немыслимо.
Однако, как бы парадоксально это ни звучало, именно это происходит в вашем браузере каждый раз, когда вы открываете веб-сайт. В процессе установки соединения устройство буквально «выкрикивает» некоторые числа в открытую сеть. Их видят провайдеры и владельцы узлов связи, но, несмотря на это, между вашим браузером и сервером формируется уникальный секретный ключ, недоступный никому из наблюдателей. Речь идет о протоколе Диффи-Хеллмана, предложенном в 1976 году и лежащем в основе большинства современных TLS-соединений.

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

Security Center
Актуальные тренды ИБ, лучшие практики защиты инфраструктуры и изменения в профильном законодательстве.
Цветовая метафора
Для начала вспомним классическую схему с красками. Алиса и Коля публично договариваются об общем цвете (например, желтом), который видит и Ева. Затем каждый выбирает собственный «секретный» цвет (Алиса — красный, Коля — синий), который держит в тайне.
Далее происходит смешивание: Алиса смешивает желтый со своим красным, получая оранжевый, а Коля — желтый с синим, получая зеленый. Этими смесями они обмениваются публично. Ева видит оранжевую и зеленую банки, но не может разделить их на исходные компоненты.
На финальном этапе Алиса добавляет к полученной зеленой банке свой секретный красный, а Коля к оранжевой — свой секретный синий. Результат у обоих одинаковый — смесь трех цветов. Ева же, имея лишь «промежуточные» цвета, не может воссоздать итоговый оттенок, так как обратный процесс разделения красок практически невозможен.
Почему эта аналогия — лишь упрощение
Хотя пример с красками красив, он не лишен недостатков, создающих ложное представление о криптографии.
Первое: В реальности краски можно разделить с помощью химии или спектрального анализа. Криптографическая же стойкость основана не на невозможности разделения, а на вычислительной сложности. Операция обратима, но для её проведения потребуются миллиарды лет, что делает взлом бессмысленным.
Второе: Аналогия не объясняет суть коммутативности операций. В основе успеха лежит использование математических действий, результат которых не зависит от порядка применения секретов, при этом оставаясь необратимым для внешнего наблюдателя.
Третье: Модель игнорирует активные атаки. Что, если Ева не просто слушает, а подменяет содержимое банок на пути от одного участника к другому? Это критическая уязвимость, о которой мы поговорим далее.
Цифры вместо красок
Настоящий Диффи-Хеллман работает на основе арифметики остатков. Представьте циферблат часов, но не на 12, а на огромное простое число делений. Вместо сложения часов мы будем использовать операцию возведения в степень по модулю — именно она обеспечивает односторонность вычислений.
Если вы делаете N шагов «умножения» по циферблату, компьютер мгновенно вычислит результат. Но если вам дадут итоговую точку, определить количество шагов (дискретный логарифм) практически невозможно за разумное время. Это и есть та самая «неразделяемая краска».
import secrets
# Выбор огромного простого числа p и генератора g
p = int("FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1...")
g = 2
# Алиса и Коля генерируют секретные экспоненты
a = secrets.randbelow(p - 2) + 1
b = secrets.randbelow(p - 2) + 1
# Публичный обмен результатами
A = pow(g, a, p)
B = pow(g, b, p)
# Вычисление общего ключа
print(pow(B, a, p) == pow(A, b, p)) # True: секрет совпал!
В современном TLS используются 2048-битные (или даже больше) числа, что делает задачу подбора ключа вычислительно невозможной для существующих мощностей.
Главная угроза
Диффи-Хеллман уязвим для атак типа «человек посередине» (MitM). Если Маша перехватит данные между Алисой и Колей, она сможет создать два отдельных ключа: один с Алисой, другой с Колей. В итоге оба будут уверены в безопасности соединения, даже не подозревая, что Маша читает и модифицирует их трафик. Вот почему в TLS протокол Диффи-Хеллмана всегда дополняется сертификатами и цифровыми подписями, подтверждающими идентичность сторон.
Эволюция протокола
Сегодня классический алгоритм в TLS 1.3 постепенно вытесняется реализациями на эллиптических кривых (например, X25519). Они обеспечивают ту же безопасность при значительно меньшем размере ключа, что ускоряет соединение. Ключевым достижением здесь стало свойство forward secrecy: даже если злоумышленник украдет долгосрочные ключи сервера, он не сможет расшифровать прошлые сессии, так как секреты генерировались случайным образом для каждого подключения.
Мир криптографии не стоит на месте, и с развитием квантовых вычислений протокол адаптируется. Внедрение постквантовых алгоритмов, таких как ML-KEM, уже идет полным ходом, чтобы защитить данные от будущих угроз. Базовая концепция — передавать не секрет, а его части, из которых ключ формируется локально — остается непревзойденным триумфом инженерной мысли.

