Сокращенный перевод статьи Good-bye ESNI, hello ECH! (Christopher Patton, The Cloudfare Blog).
Сегодня ряд крайне важных параметров TLS-соединений передается в явном виде. Таким образом, у третьих лиц есть доступ к метаданным, включая информацию о конечных точках, характере использования соединения и так далее.
ECH может исправить это, закладывая основу для добавления будущих функций безопасности и повышения производительности TLS. Влияние на конфиденциальность конечных пользователей при этом будет минимальной. ECH — это продукт тесного сотрудничества между учеными и технологическими компаниями. Среди участников: IETF (Инженерный совет интернета), Cloudflare, Fastly, Mozilla и другие.
ECH основан на передовых технологиях, которые только начинают применяться. Например, DNS over HTTPS. Как таковой, протокол еще не готов к развертыванию в масштабе интернета, но этот текст поможет лучше понять, какие возможности дает ECH.
Предыстория
История TLS — это история интернета. По мере развития сети, протокол развивался с учетом постоянно меняющихся требований безопасности, опыта использования и новых угроз.
Клиент и сервер не просто обмениваются ключами. Они обсуждают широкий спектр функций и параметров: точный метод обмена ключами, алгоритм шифрования, процесс аутентификации, какой протокол прикладного уровня использовать после рукопожатия и многое другое. Все эти параметры так или иначе влияют на свойства безопасности канала связи.
Пример такого параметра — расширение SNI (Server Name Indication, Индикация имени сервера). С его помощью клиент сообщает серверу, какой сайт он хочет посетить. Для интернета это очень важно, так как сейчас многие серверы находятся за одним TLS-оператором. Оператор использует SNI для определения того, кто будет аутентифицировать соединение: без этого невозможно будет узнать, какой TLS-сертификат представить клиенту.
Проблема заключается в том, что SNI идентифицирует сервер, к которому клиент хочет подключиться, потенциально позволяя третьим лицам получать множество метаданных. Но это не единственный чувствительный к конфиденциальности параметр, который клиент и сервер обговаривают между собой.
Другой параметр — это расширение ALPN (Application-Layer Protocol Negotiation, Согласование протоколов уровня приложений). Оно используется, чтобы принимать решение, какой протокол прикладного уровня использовать после установки TLS-соединения. Клиент отправляет серверу список используемых приложений (электронная почта, мессенджеры и другое), которые используют TLS, а сервер сообщает клиенту свой выбор. Таким образом, клиент и сервер приходят к согласию, для каких возможностей и задач может быть использовано соединение.
Некоторые функции настолько чувствительны к конфиденциальности, что не включаются в рукопожатие сразу. Ранее высказывалась идея заменить обмен ключами в TLS на обмен ключами c аутентификацией паролем. Это позволит использовать аутентификацию на основе пароля вместе (или вместо) аутентификации на основе сертификата, что сделает TLS более надежным и подходящим для более широкого круга приложений. Проблема конфиденциальности здесь такая же, как и в случае с SNI: серверы обычно ассоциируют уникальный идентификатор который используется для получения учетных данных c каждым клиентом (например имя пользователя или адрес электронной почты). Клиент должен каким-то образом передать его серверу во время рукопожатия. Если отправлять эту информацию в открытом виде, она будет доступна любому внешнему наблюдателю в сети.
Необходимое условие для устранения проблемы — шифрование сообщений о рукопожатии в дополнение к данным приложения. Звучит достаточно просто, но возникает проблема. Как клиент и сервер согласовывают ключ шифрования, если рукопожатие само по себе является средством обмена ключами? Некоторые параметры, конечно же, должны отправляться в открытом виде, поэтому целью ECH является шифрование всех параметров рукопожатия, за исключением тех, которые необходимы для завершения обмена ключами.
Чтобы понять ECH и решения в его основе, стоит немного разобраться в истории шифрования рукопожатий в TLS.
Шифрование рукопожатий в TLS
До выхода TLS 1.3 рукопожатия не шифровались. После разоблачений Сноудена в 2013 году сообщество IETF (Инженерный совет интернета) начало думать над противодействием угрозе, которую представляет собой массовое наблюдение за открытым интернетом. Когда в 2014 году начался процесс стандартизации TLS 1.3, одной из целей разработки было максимально возможное шифрование рукопожатий. К сожалению, стандарт TLS 1.3 не может обеспечить этого, а некоторые параметры, в том числе SNI, все еще передаются в чистом виде. Давайте разберемся, почему.
Работа протокола TLS 1.3 показана на рисунке 1. Шифрование рукопожатия начинается как только клиент и сервер договариваются об общей секретной информации. Для этого клиент отправляет серверу ключ с сообщением ClientHello, а тот отвечает ему сообщением ServerHello со своим собственным ключом. Обменявшись этим, клиент и сервер могут получить shared secret (данные, известные только заинтересованным сторонам в защищенном обмене данными). Каждое последующее рукопожатие шифруется с помощью ключа трафика, полученного из shared secret.
Первое зашифрованное сообщение в рукопожатии — EncryptedExtensions от сервера. Его задача — защитить чувствительные параметры рукопожатия, включая ALPN-расширение сервера, которое содержит приложение, выбранное из клиентского списка ALPN-клиентов. Параметры обмена ключами отправляются в незашифрованном виде в сообщениях ClientHello и ServerHello. Все параметры рукопожатия, как чувствительные, так и нет, отправляются в сообщении ClientHello.
Рисунок 1: Рукопожатие TLS 1.3.
Взглянув на рисунок 1 можно задуматься, как переделать процесс рукопожатия так, чтобы зашифровать больше компонентов, возможно, за счет дополнительных задержек (большего количества циклов в сети). Однако, такие расширения, как SNI создают классическую проблему «курица или яйцо».
Клиент ничего не зашифрует, пока не проверит идентичность сервера (это работа сообщений CertificateVerify), а сервер не подтвердит, что знает shared secret (это работа сообщения Finished). Эти меры обеспечивают аутентификацию с помощью обмена ключами, предотвращая таким образом атаки monster-in-the-middle (MITM), где хакер выдает себя клиенту за сервер, что позволяет расшифровать сообщения. Поскольку SNI нужен серверу для выбора сертификата, он должен быть передан до аутентификации с помощью обмена ключами.
В общем, обеспечение конфиденциальности параметров рукопожатия, используемых для аутентификации, возможно только в том случае, если клиент и сервер уже имеют общий ключ шифрования. Но откуда может взяться этот ключ?
Полное шифрование рукопожатий в TLS 1.3. Интересно, что полное шифрование рукопожатий было однажды предложено в качестве основной функции TLS 1.3. В ранних версиях протокола (draft-10, около 2015 года) сервер предлагал клиенту долгоживущий открытый ключ во время рукопожатия, который клиент использовал для шифрования при последующих рукопожатиях. Эта схема пришла из протокола под названием OPTLS, который, в свою очередь, был основан на протоколе QUIC.
Режим назвали «0-RTT» и он использовался в первую очередь для того, чтобы дать клиенту возможность отправлять данные приложения до завершения процесса рукопожатия.
Кроме того, это позволило бы клиенту зашифровать первую серию сообщений рукопожатия следующую за ClientHello, включая его собственные EncryptedExtensions, которые могли использоваться для защиты конфиденциальных параметров рукопожатия клиента.
Но эта функция не была включена в окончательную версию стандарта RFC 8446, опубликованную в 2018 году. Главной причиной было то, что сложность реализации перевешивала потенциальную пользу. Кроме того, функция никак не защищает первоначальное рукопожатие, когда клиент узнает публичный ключ сервера. Такие параметры, как SNI все равно будут передаваться в открытом виде.
Тем не менее, эта схема примечательна как предшественница других механизмов шифрования рукопожатий, таких как ECH, которые используют шифрование с открытым ключом для защиты чувствительных параметров ClientHello.
До ECH было (и есть) ESNI
Непосредственным предшественником ECH было расширение Encrypted SNI (ESNI). Как следует из названия, целью ESNI было обеспечение конфиденциальности SNI. Работает оно так. Клиент шифрует свое расширение SNI под открытым ключом сервера и отправляет шифрованный текст на сервер. Сервер пытается расшифровать текст, используя секретный ключ, соответствующий его открытому ключу. Если дешифровка прошла успешно, сервер устанавливает соединение, используя расшифрованный SNI. В противном случае, он прерывает рукопожатие. Весь процесс показан на рисунке 2.
Рисунок 2: Рукопожатие TLS 1.3 с расширением ESNI. Оно идентично рукопожатию TLS 1.3, за исключением того, что расширение SNI было заменено на ESNI
Несмотря на то, что ESNI сделал значительный шаг вперед, он не соответствует цели полного шифрования рукопожатий. Помимо того, что ESNI защищает только SNI, он уязвим к нескольким сложным атакам, которые, хотя и трудновыполнимы, но указывают на теоретические недостатки в конструкции протокола, которые необходимо устранить. Однако практическая польза от ESNI в плане конфиденциальности существенна.
Плюсы и минусы ECH
Цель ECH — полностью зашифровать ClientHello, закрыв соответствующий пробел в TLS 1.3 и ESNI, защитив все чувствительные к конфиденциальности параметры рукопожатия. Подобно ESNI, протокол использует открытый ключ, распространяемый через DNS и полученный с помощью DoH. Однако в ECH есть улучшения в распределении ключей, которые делают протокол более устойчивым к несовпадениям в DNS-кэше. В то время как ESNI-сервер прерывает соединение в случае сбоя дешифровки, ECH-сервер пытается завершить рукопожатие и предоставить клиенту открытый ключ, который он может использовать для повторных попыток соединения.
Но как сервер может завершить рукопожатие, если он не может расшифровать ClientHello? Как показано на рисунке 3, протокол ECH включает два ClientHello сообщения:
- ClientHelloOuter, который отправляется в открытом виде;
- ClientHelloInner, который зашифрован и отправляется в качестве расширения ClientHelloOuter.
Сервер завершает рукопожатие только одним из этих ClientHello: если дешифровка прошла успешно, то он продолжает работать с ClientHelloInner; в противном случае, он продолжает работать с ClientHelloOuter. Как минимум, оба ClientHello должны содержать параметры рукопожатия, необходимые для аутентифицированного сервером обмена ключами.
Рисунок 3: Рукопожатие TLS 1.3 с расширением ECH.
Такая конструкция решает большинство проблем безопасного развертывания шифрования рукопожатий. Важно отметить, что ECH был задуман не в вакууме. Протокол отражает различные точки зрения сообщества IETF, и его разработка согласуется со стандартами IETF. Актуальная спецификация ECH сегодня достаточно стабильна. Но остается еще несколько детальных вопросов, которые нужно решить.
Заключение
В конечном итоге цель ECH — гарантировать, чтобы TLS-соединения с разными серверами сделанные с помощью одного ECH-провайдера были неотличимы друг от друга. То есть, никто не должен знать, к какому серверу вы подключились, или какие параметры рукопожатия были согласованы. Как только эта цель достигнута, уровень конфиденциальности немедленно повышается и появляется возможность для развертывания новых функций TLS без ущерба для конфиденциальности.
Старая версия TLS-рукопожатия слишком уязвима для сторонних наблюдателей в сети. И расширение ECH должно устранить этот пробел за счет шифрования всего процесса рукопожатия. Это поможет сохранить конфиденциальность конечных пользователей по мере развития протокола.
ECH нуждается в доработке, чтобы помешать третьим лицам анализировать трафик. Например, длина зашифрованного ClientHello может дать третьим лицам достаточную подсказку о его ценности. Этот риск велик для доменных имен, которые или слишком короткие, или слишком длинные. Поэтому важно сделать так, чтобы длина каждого зашифрованного текста не зависела от значений параметров, чувствительных к конфиденциальности. Повышение устойчивости ECH — важное направление для будущей работы, которой еще много.