TLS 1.3: на пути к внедрению

TLS (Transport Layer Security) - протокол, предназначенный для защищённого обмена данными между узлами сети, по открытым каналам. В современном Интернете на TLS приходится большая часть трафика, передаваемого в защищённом режиме. Например, именно этот протокол служит транспортом для защищённой версии HTTP - HTTPS, что сразу же делает TLS чрезвычайно важным протоколом.

Первоначально, защищённый протокол для работы с серверами Интернета назывался SSL (Secure Sockets Layer), а первая версия SSL предназначалась для браузера Netscape Navigator и разрабатывалась внутри компании Netscape в 1994-95 гг. В последующие годы, вместе с внедрением рекомендаций RFC, протокол переименовали в TLS. Это произошло скорее по юридическим, а не техническим причинам: так, версия TLS 1.0, за исключением ряда тонкостей, технически эквивалентна третьей версии протокола SSL (SSLv3). Сейчас каноническим обозначением является TLS. Версия TLS 1.0 вышла (в качестве рекомендации RFC 2246) в 1999 году. Две следующие версии протокола: 1.1 и 1.2, соответственно, в 2006 (RFC 4346) и в 2008 (RFC 5246). TLS 1.2 на настоящий момент является рекомендуемой версией протокола, а с момента публикации этой версии - прошло уже около десяти лет. Новая версия, обзор которой содержит настоящая статья, - TLS 1.3. Разработка новой версии протокола в рамках процесса IETF началась в 2014 году, а соответствующий RFC (март 2018) близок к статусу стандарта (draft-28). Поддержка вносится в распространённые библиотеки, например, в OpenSSL 1.1.1.

Идеи и ощущения, что TLS нуждается в кардинальной переработке, циркулировали в сообществе IETF, и в кругах специалистов по защите информации, примерно с начала 2010-х годов. Несмотря на то, что, помимо трёх версий TLS, вышедших в 1999-2006, многие дефекты протокола становились предметами дополнительных RFC, требовалась ревизия самих основ. Этот процесс чрезвычайно активизировался после того как в 2013-2014 гг в прессе возникла шумиха, связанная с "разоблачениями Эдварда Сноудена" деятельности Агентства Национальной Безопасности США в области технической разведки (это основная функция данного агентства), в том числе, по массовому перехвату пользовательского интернет-трафика. Разработка TLS 1.3 отличалась от всех предыдущих версий даже целеполаганием. Например, версия TLS 1.2, хоть и содержала целый ряд серьёзных изменений, но без сомнения являлась всего лишь развитием 1.1; то же самое можно сказать о 1.1 и 1.0. Новая же версия, в соответствии с планом, оказалась разработана фактически с нуля. TLS 1.3 настолько сильно отличается, что можно было бы считать его другим протоколом, а не новой версией. Некоторое время обсуждался вопрос о том, не нужно ли переименовать версию, например, в TLS2 (по аналогии с HTTP/2), или использовать какое-то другое название, чтобы отразить степень отличия от TLS 1.2. Но радикального изменения номера версии всё же не произошло и новый протокол называется TLS 1.3.

От предыдущих версий TLS 1.3 унаследовал общую логику построения. Как и прежде, протокол предназначен для решения задач аутентификации узлов, обеспечения конфиденциальности и целостности (защиты от подмены и изменений) передаваемых данных. При этом TLS предполагает, что между узлами уже установлено надёжное соединение (открытое), однако третья сторона может как угодно вмешиваться в его работу - подменять пакеты, препятствовать их доставке, разрывать соединение и так далее. TLS - клиент-серверный протокол. В обычных сценариях применения, роли клиента и сервера в TLS соответствуют ролям при установлении TCP-соединения (поверх которого работает TLS): то есть, клиентом TLS оказывается клиент TCP. Установление соединения всегда начинает клиент.

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

Проиллюстрируем эффективное использование метаинформации при анализе TLS-соединений следующим примером. Рассмотрим TLS-сеанс между браузером и веб-сервером, соответствующий штатной (без использования дополнительных средств защиты информации) работе пользователя с некоторым веб-интерфейсом, например, заполнение веб-формы на сайте. Версия протокола - до TLS 1.3. В момент установления соединения, третья сторона, прослушивающая канал, получает информацию о следующих параметрах соединения:

1) Время установления соединения и его продолжительность. Это очевидные параметры, они определяются из состава переданных TLS-сообщений.

2) IP-адрес сервера и IP-адрес клиента. Известны из TCP-соединения, не зависят от TLS напрямую, однако протокол неявно подразумевает, что адреса клиента и сервера TCP-соединения - совпадают с адресами клиента и сервера на уровне TLS; в частности, типовая реализация протокола не предполагает проксирования TLS-данных (такое проксирование может быть реализовано дополнительными средствами).

3) Сведения о том, устанавливал ли браузер соединение с данным TLS-сервером ранее. В TLS предусмотрены механизмы ускоренного установления соединения, а они подразумевают передачу дополнительных "тикетов" в сторону сервера, эти тикеты передаются в открытом виде.

4) Имя сервера. Символьное имя сервера (вида example.com) передаётся браузером в открытом виде на этапе установления соединения.

5) Дополнительные имена сервера. На этапе установления соединения, подразумевающего аутентификацию сервера (а это свыше 99% соединений HTTPS), сервер передаёт TLS-сертификат в открытом виде. Сертификат содержит поля с указанием различных имён, для которых данный сертификат валиден. Кроме того, открытый ключ из сертификата также позволяет идентифицировать сервер.

6) Выбранные криптографические параметры TLS-соединения. Шифр, алгоритм электронной подписи и вычисления кода аутентификации (имитовставки) - передаются в открытом виде.

7) Примерный объём переданных данных, примерные действия, выполненные пользователем. Прослушивающая сторона может определить длину передаваемых TLS-записей, штатная работа протокола предыдущих версий не подразумевает каких-то эффективных средств маскировки длины сообщений, если они содержат достаточное количество байтов (маскировать длину данных необходимо дополнительно). Например, если пользователь загружал через веб-форму файл существенного объёма, то количество переданных байтов, очевидно, будет отличаться от сценария, когда пользователь просто закрыл веб-форму. Анализ длины переданных записей, порядка их следования, и сопоставление результата с особенностями веб-интерфейса, нередко позволяет точно определить, какие именно действия совершил пользователь.

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

Типичный сеанс TLS состоит из трёх основных этапов: установление соединения, обмен данными, завершение соединения. При этом, первый этап, - установление соединения, - имеет ключевое значение для сеанса в целом, так как именно на этом этапе проводится аутентификация, обмен ключами и выбирается набор алгоритмов защиты информации, которые будут использоваться узлами для обмена данными. Операции по установлению соединения логически объединены в специальную фазу протокола - TLS Handshake. (В терминологии RFC: внутри TLS выделены два протокола - установление соединения и протокол обмена записями.) И если в предыдущих версиях TLS установление соединения от версии к версии менялось не радикально, то в 1.3 - Handshake переделан полностью: предыдущие версии не совместимы с новой.

Handshake представляет собой обмен строго определёнными сообщениями, осуществляемый в определённой последовательности. Рассмотрим основные фазы для версии TLS 1.2 (в предыдущих версиях, начиная с TLS 1.0., Handshake сходен с 1.2). Прежде всего, Handshake бывает полный и сокращённый. Сокращённый вариант, как упоминалось выше, используется при повторном установлении соединения между узлами - он позволяет экономить время, необходимое для доставки пакетов, и вычислительные ресурсы. Соответственно, в сокращённом варианте опущены некоторые шаги. Для того, чтобы сокращённый вариант стал возможен, узлы должны предварительно провести полный Handshake (существуют некоторые исключения). Мы не рассматриваем сокращённый вариант для TLS 1.2 и более ранних версий, но ниже отдельно остановимся на сокращённом варианте для TLS 1.3.

Полный вариант Handshake требует отправки запроса клиента, получения ответа сервера, отправки ответа и завершающего сигнала клиента и получения завершающего сигнала от сервера. То есть, два полных двухсторонних обмена сообщениями (или четыре "полудуплексных"). Процесс в версии 1.2 (см. Схему 1) начинается с отправки клиентом сообщения ClientHello, обозначающего, что клиент предлагает установить TLS-соединение. Это сообщение, в частности, содержит предпочитаемые клиентом параметры криптосистем, а также другую сервисную информацию. Если сервер смог успешно обработать ClientHello и готов принять соединение, то он отвечает сообщением ServerHello и набором дополнительных сообщений, например, сообщением, содержащим серверный TLS-сертификат - это наиболее распространённый случай. Ответ сервера также содержит выбранные сервером параметры криптосистем. В TLS решение об используемых параметрах принимает сервер, который лишь руководствуется предоставленными клиентом в ClientHello опциями в части определения поддерживаемых клиентом вариантов. Если настройки клиента не соответствуют требованиям сервера, соединение окажется невозможным. (Параметры криптосистем мы рассмотрим ниже.)

При успешной обработке серверного ответа, клиент отправляет подтверждающие сообщения и переходит в защищённый режим обмена данными (так как к этому моменту уже согласован криптографический контекст). Переход в защищённый режим обозначается отправкой специального сигнала: ChangeCipherSpec. Далее следует сообщение об окончании клиентской части Handshake - это сообщение называется Finished. Сервер, соответственно, также должен перейти в защищённый режим и отправить сигнал о завершении Handshake. Как только узлы обменялись сигналами о завершении Handshake, начинается обмен защищёнными TLS-записями, в которых передаются полезные данные приложения. В рамках процесса установления соединения узлы определяют общий криптографический контекст, который, в дальнейшем, служит для защиты передаваемых данных. Handshake целиком - также оказывается защищён, но с одной оговоркой: стороны получают возможность провести валидацию сообщений Handshake только перед самым завершением данной фазы протокола. Дело в том, что проверка реализована по следующему алгоритму: сообщение Finished содержит значение хеш-функции от всех предыдущих сообщений Handshake. Finished передаётся в защищённом режиме, а значит, принявшая данное сообщение сторона может проверить его целостность. Каждая из сторон имеет копии всех полученных и переданных к этому моменту Handshake-сообщений, соответственно, может вычислить значение хеш-функции и сравнить его с полученным в Finished. Если Finished не подверглось изменению, а значение хеш-функции совпало, то и Handshake признаётся подлинным. Тем не менее, такой алгоритм проверки позволил, например, реализовать весьма показательную атаку CVE-2015-4000 (Logjam) с понижением уровня защиты. Основной механизм атаки состоит в том, что активная третья сторона подменяет криптографические параметры в сообщении ClientHello, вынуждая уязвимый сервер выбрать заведомо слабые, после чего на лету вычисляет сессионный секрет и, таким образом, может подделать сообщения Finished и перехватить сессию.

CLIENT                                SERVER

ClientHello      ------->

                <-------              ServerHello
                                      + Сертификат
                                      [...]
+ [...]
ChangeCipherSpec
-----------------------------------------------------
Finished         ------->
                                      [...]
                                      ChangeCipherSpec
                <-------              Finished 

Данные приложения <--->             Данные приложения

Схема 1. Упрощённая схема полного Handshake в TLS 1.2

Для успешной работы в защищённом режиме, стороны TLS-соединения должны использовать согласованные криптографические алгоритмы и их параметры. Для каждого сеанса определяющую роль играют следующие элементы: симметричный шифр, алгоритм вычисления кода аутентификации сообщения (имитовставки), хеш-функция, набор сеансовых ключей. Так как стороны используют для установления соединения открытый канал, требуется общий алгоритм получения сеансового секрета (под таким секретом подразумевается число, служащее для генерации набора симметричных секретных ключей). Типовым вариантом здесь является протокол Диффи-Хеллмана (далее DH) и механизм электронной подписи (далее - просто "подпись"). До сих пор встречается устаревший вариант, с передачей секрета клиентом в сторону сервера при помощи шифрования RSA (так называемый вариант Static RSA, прямо запрещённый протоколом в версии 1.3) - RSA, условно говоря, заменяет здесь DH. Сочетание криптосистемы электронной подписи и DH, шифра, хеш-функции, других элементов, используемых при установлении соединения, называется шифронабором. Эти сочетания закреплены в рекомендациях, и в документации обозначаются текстовыми строками, состоящими из названий алгоритмов и криптосистем (в протоколе - шифронаборам соответствует двухбайтовый код). Например, сочетание символов TLS_RSA_WITH_AES_128_CBC_SHA обозначает, что для TLS-соединения будут использованы: криптосистема RSA для передачи сеансового секрета, симметричный шифр AES разрядностью 128 бит в режиме CBC для шифрования данных, SHA-1 в качестве хеш-функции. Современный вариант: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA256 - протокол DH на эллиптической кривой для сеансового секрета, криптосистема подписи ECDSA ("эллиптический" вариант DSA) для удостоверения параметров DH, симметричный шифр AES разрядностью 256 бит в режиме GCM для шифрования данных и хеш-функция SHA-256.

Напомним, что симметричный шифр - это набор обратимых преобразований открытого текста, позволяющий, при условии знания ключа, получить секретный текст и, соответственно, решить обратную задачу: восстановить из секретного - открытый. Операции называются шифрованием и расшифрованием. Симметричность состоит в том, что знание ключа шифрования позволяет легко расшировать секретный текст (напротив, асимметричные системы оперируют парой связанных ключей: открытым - для шифрования; секретным - для расшифрования). Шифры принято делить на блочные и потоковые. Блочные - в качестве элементарного объекта оперируют блоками данных фиксированной длины, входной поток должен быть, соответственно, разбит на подходящие блоки. Потоковые шифры - зашифровывают непосредственно поток данных, без необходимости разбиения на блоки. В современной практике использования шифров это деление достаточно условно. Существует понятие "режима шифрования", которое обозначает алгоритм применения шифра, рассматриваемого как криптографический примитив, к входным данным, в частности, подходящий режим шифрования позволяет использовать блочный шифр как потоковый. Подробно режимы шифрования и сами шифры, используемые в TLS, рассмотрены в отдельном описании TLS. Симметричные шифры необходимы в TLS для защиты потока данных, так как асимметричные криптосистемы, - например, RSA, - для этого по ряду причин не годятся, прежде всего, из-за очень низкой производительности. В TLS используются именно наборы симметричных ключей: клиент и сервер применяют отдельные ключи для передаваемых и принимаемых сообщений. Так как ключи симметричные, то ключ приёма (или чтения) на стороне клиента соответствует ключу передачи (или записи) на стороне сервера. Это важная особенность TLS.

Протокол Диффи-Хеллмана позволяет узлам получить общий секрет, обменявшись парой открытых значений. В общем случае, DH уязвим к активной атаке посредника ("человек посередине"), поэтому требуется аутентификация параметров и ключей. В TLS - аутентифицируются серверные параметры DH и серверный ключ, это делается с помощью подписи, которую также вычисляет сервер. Необходимые для проверки подписи данные - передаются в серверном TLS-сертификате.

(TLS предусматривает и иные способы получения защищённого контекста, в том числе, базирующиеся на общем для узлов секрете, который распределяется заранее и за пределами TLS. Кроме того, возможно использование TLS без шифрования - то есть, данные передаются в открытом виде, но с аутентификацией узлов и защитой целостности. Все эти варианты являются редкими. Последний, например, предлагается для использования в индустриальных системах управления - SCADA. Другой редко используемой на практике возможностью TLS является двухсторонняя аутентификация узлов: обычно аутентифицируется только сервер клиентом, однако протокол предусматривает и аутентификацию клиента сервером, что реализуется с использованием клиентского TLS-сертификата.)

Итак, полный вариант установления соединения в TLS до версии 1.3 предусматривает передачу большого количества сообщений в открытом виде. Аутентификация Handshake - проводится при его завершении.

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

      Client                                               Server

Key  ^ ClientHello
Exch | + key_share*
     | + signature_algorithms*
     | + psk_key_exchange_modes*
     v + pre_shared_key*         -------->
                                                       ServerHello  ^ Key
                                                      + key_share*  | Exch
                                                 + pre_shared_key*  v
                                             {EncryptedExtensions}  ^  Server
                                             {CertificateRequest*}  v  Params
                                                    {Certificate*}  ^
                                              {CertificateVerify*}  | Auth
                                                        {Finished}  v
                                 <--------     [Application Data*]
     ^ {Certificate*}
Auth | {CertificateVerify*}
     v {Finished}                -------->
       [Application Data]        <------->      [Application Data]

Схема 2. Полный Handshake TLS 1.3, версия 26 черновика рекомендации draft-ietf-tls-tls13-26

Рассмотрим в деталях схему установления соединения в TLS 1.3 (Схема 2) и сравним её с реализациями предыдущих версий. Здесь так же присутствуют две стороны - клиент и сервер, - а соединение инициирует клиент. С точки зрения передачи сообщений, Handshake короче на одну итерацию (половину цикла двухстороннего обмена сообщениями) и в 1.3 клиент переходит к отправке данных приложения на один шаг раньше. Сравним с 1.2 (Схема 1): для того, чтобы перейти к защищённому обмену данными при полном Handshake, в версии 1.2 клиент должен отправить ClientHello и получить ответ (один цикл), отправить набор сообщений с Finished и получить ответ (второй цикл). В 1.3 отправка данных начинается без ожидания ответа на клиентское Finished, так как последовательность отправки завершающих сообщений изменена: сервер отправляет Finished раньше. Данное решение концептуально схоже с расширением TLS под названием False Start, которое предложенно в RFC 7918 (откуда, собственно, идея и перекочевала в TLS 1.3).

На Схеме 2 в фигурных скобках представлены сообщения, которые передаются в зашифрованном виде. То есть, уже ответные сообщения сервера в TLS 1.3 - зашифрованы. Так как на момент отправки этих сообщений сервером полноценный криптографический контекст ещё не согласован, для их защиты используется отдельный набор ключей. Это первое фундаментальное отличие TLS 1.3 от предыдущих версий: используемые криптографические ключи разбиты на несколько групп и введены отдельные ключи для выполнения Handshake. Серверный TLS-сертификат теперь передаётся в зашифрованном виде, соответственно, пассивно прослушивающая канал сторона уже не может (не имея ключей) прочитать данные из сертификата. Это заметно снижает объём утечки метаинформации о соединении (см. перечень метаинформации выше). Более того, при необходимости, протокол вообще позволяет скрыть сам факт передачи серверного TLS-сертификата.

В протоколе установления соединения (Handshake) TLS 1.3 спецификация выделяет три этапа:

1) выработка общего набора криптографических ключей (на основе секрета); 2) полное определение параметров соединения; 3) аутентификация (сервера и клиента).

К первому этапу (см. Схему 2) относятся группы ClientHello и ServerHello, а также дополнения, обозначенные на схеме символом '+'. Именно на этом этапе стороны получают первый набор симметричных ключей, которые генерируются на основе секрета (handshake_traffic_secret), в свою очередь, полученного по протоколу DH (но это только один из вариантов). Так как соединение инициирует клиент, то он и передаёт первоначальные параметры DH, в том числе, открытый ключ клиента. Для этого служит расширение key_share в ClientHello. Ответную часть DH сервер присылает в своём блоке key_share, входящем, соответственно, в ServerHello. Спецификацией предусмотрен и другой вариант получения общего секрета - использование заранее заданного секретного ключа, известного узлам (PSK - Pre-Shared Key). Для его передачи служит расширение ClienHello/ServerHello pre_shared_secret. В отличие от открытых параметров DH, секретный ключ, очевидно, нельзя передавать по открытому каналу. Поэтому клиент передаёт только идентификаторы секретов (секретных ключей), из которых сервер выбирает подходящий и возвращает выбранный идентификатор клиенту в ответном ServerHello. Соответствующие ключи могут быть распределены независимо от канала TLS, такая схема является одной из самых защищённых. Также возможен вариант, когда клиент получает секрет от сервера в рамках предыдущей сессии TLS, этот механизм сходен с возобновлением сессии в предыдущих версиях протокола, а в 1.3 используется для установления TLS-соединения по сокращённой схеме.

Второй этап включает серверные сообщения EncryptedExtensions и, при необходимости аутентификации клиента, CertificateRequest. Сообщение EncryptedExtensions также является нововведением TLS 1.3. Сообщение предназначено для передачи в зашифрованном виде расширений Handshake (иногда называются также "дополнениями"). Данные расширения играют очень важную роль в протоколе, так как именно в них передаются разнообразные параметры "тонкой настройки". Ключевое отличие здесь состоит в том, что расширения зашифрованы. Сами по себе, расширения присутствовали и в предыдущих версиях TLS, однако передавались в открытом виде (соответствующее сообщение называется Extensions) и, таким образом, способствовали утечкам метаинформации, а также предоставляли направления для атак на протокол.

На третьем этапе, представленном наборами сообщений Certificate, CertificateVerify и Finished, происходит аутентификация сервера и клиента. Как и в предыдущих версиях TLS, аутентификация может быть полностью исключена (анонимный режим, раздел C.5. спецификации), но типичный сценарий использования подразумевает аутентификацию, по крайней мере, сервера клиентом, а анонимный режим строго не рекомендуется.

Как отмечено выше, одной из важнейших особенностей TLS 1.3 является использование нескольких наборов симметричных ключей. Спецификация протокола распределяет эти ключи в иерархию по уровням, относительно начала сессии. Ключи более "глубоких" уровней, - то есть, относящиеся к этапам, которые находятся ближе к полноценному защищённому соединению, - генерируются с использованием ключей более "высоких" уровней. На первом, самом раннем или "высоком", уровне, находятся ключи, предназначенные для шифрования первого запроса клиента при использовании сохранённого общего секрета. Такая ситуация возникает только при повторном возобновлении сессии, по сокращённому варианту Handshake. Второй уровень ключей используется в полной схеме установления соединения для шифрования Handshake-сообщений и базируется на секрете, полученном в рамках обмена Диффи-Хеллмана. Следующий уровень, третий, - это сессионные симметричные ключи, которые защищают основной полезный трафик (они порождаются на основе общих секретов - server_traffic_secret, client_traffic_secret). Согласно спецификации, ключи третьего уровня могут периодически обновляться. Если взглянуть на предыдущие версии TLS, то там ничего подобного не встречается, а присутствует единственный набор симметричных ключей, которые используются для шифрования полезной нагрузки.

Внедрение иерархии ключей привело к тому, что в Handshake больше не используется сигнал о переходе к защищённой передаче сообщений - ChangeCipherSpec. Кроме того, удалены обособленные сообщения, в которых ранее передавались параметры ключевого обмена клиента и сервера (в TLS 1.2 это ClientKeyExchange, ServerKeyExchange и ServerHelloDone, на схеме 1 они не приводятся). Параметры, играющие ту же роль в TLS 1.3, перекочевали в ClientHello и ServerHello. О завершении серверного набора Handshake-сообщений в 1.3 сигнализирует Finished.

Основные причины, повлёкшие столь глубокое изменение архитектуры Handshake, логически разбиваются на два направления. Во-первых, требовалось ускорить проведение первичного установления соединения. TLS становится всё более распространённым протоколом, он массово используется крупнейшими сервисами Интернета, среди которых Google, Facebook и др. Так, основным "поставщиком трафика" является HTTPS - защищённая версия HTTP, работающая поверх TLS. HTTPS использует большинство современных популярных веб-сайтов. Рассмотрим такой аспект, как дополнительная итерация протокола, связанная с отправкой сообщения сервером клиенту. В современной глобальной Сети, время, необходимое для доставки сообщения по TCP, часто измеряется десятками миллисекунд. Предположим, что данный показатель - 50 мс (это довольно быстро). Если популярный веб-сервис обслуживает ежесекундно десять тысяч новых TLS-соединений, то 50 мс превращаются в 500 секунд ожидания, которые необходимо разделить по дескрипторам соединения и физическим интерфейсам, а это дополнительные затраты, в том числе, выражающиеся в закупке и обслуживании дополнительного аппаратного обеспечения. То есть, уже из этой грубой оценки видно, что для высоконагруженных сервисов экономия даже одной итерации отправки пакетов, которую даёт полный Handshake версии 1.3, приводят к существенному снижению затрат на обслуживание пользовательских соединений.

Второе направление - стремление повысить общую секретность протокола. Нововведения призваны минимизировать количество шагов, осуществляемых в открытом виде, или, другими словами, сократить объём сигнатуры, соответствующей использованию протокола и доступной при прослушивании канала. Новая версия Handshake не делает протокол "невидимым" - уверенно обнаружить TLS-соединения 1.3 в трафике, используя автоматические инструменты, нетрудно. Так, достаточно устойчивым признаком остаётся пара сообщений ClientHello и ServerHello, которые хоть и поменяли формат, но всё равно передаются в открытом виде. При этом, например, новые расширения ClientHello, предназначенные для реализации обмена по протоколу Диффи-Хеллмана (key_share), могут служить дополнительным признаком TLS-соединения. Однако по сравнению с предыдущими версиями, ситуация стала заметно более секретной. Сравним возможности утечки метаинформации с TLS 1.2 (см. выше).

1) Время установления соединения и его продолжительность. Эти параметры остаются доступными по очевидным причинам.

2) IP-адрес сервера и IP-адрес клиента. Также остаются известны из TCP-соединения.

3) Сведения о том, устанавливал ли браузер соединение с данным TLS-сервером ранее. Благодаря наличию нового сокращённого Handshake (0-RTT, см. ниже), также оказывается возможно определить факт повторного соединения, однако из сообщений, передаваемых в открытом виде, исчезли уникальные идентификаторы, которые могли быть использованы для каталогизации сессий TLS 1.2 и более ранних версий.

4) Имя сервера. Утечка закрыта только частично. Символьное имя сервера передаётся в открытом виде, однако протокол предлагает некоторые базовые механизмы, которые позволят построить схему защиты от утечки. Соответствующее расширение, в котором передаётся имя сервера, называется SNI (Server Name Indication). В процессе работы над новым протоколом несколько раз поднимался вопрос о внедрении зашифрованного поля SNI (Encrypted SNI), но такой подход не получил поддержки. Один из предложенных способов защиты от утечки подразумевает использование двух значений SNI - первое значение служит "прикрытием" и передаётся в открытом виде, однако после установления первого соединения клиент, получив специальный тикет, может установить повторное соединение уже с другим значением имени сервера, которое передаётся в зашифрованном расширении.

5) Дополнительные имена сервера. Так как серверный сертификат передаётся в зашифрованном виде, данный пункт к TLS 1.3 не применим - здесь утечки не происходит.

6) Выбранные криптографические параметры TLS-соединения. Поправка от 29/06/2018: выбранный сервером набор криптосистем в TLS 1.3 также доступен пассивно прослушивающей канал стороне; соответственно, пассивное прослушивание позволяет определить начальные криптографические параметры, выбранные сторонами в Handshake-сообщениях (списки этих параметров, в том числе, группы DH, известны из спецификации протокола, поэтому, новой информации тут минимум).

7) Примерный объём переданных данных, примерные действия, выполненные пользователем. В TLS 1.3 этот канал полностью не исключается, однако для защиты - дополнительные меры предусмотрены прямо в спецификации (Record Padding), например, это выравнивание длины TLS-записей и передача пустых записей.

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

В TLS 1.3 имеется схема сокращённого установления соединения, которая носит название 0-RTT (Zero Round-Trip Time - нулевая задержка приёма-передачи). Эта схема потенциально быстрее всех предыдущих вариантов сокращённого Handshake, да и вообще является оптимальной, в смысле передачи сообщений между узлами (откуда и возникло упоминание Zero Round-Trip). Для использования данной схемы стороны уже должны согласовать общий секрет. В 0-RTT клиент начинает соединение с отправки ClientHello, с указанием общего секрета, за которым сразу же следуют данные уровня приложений (полезной нагрузки). Например, этой полезной нагрузкой может быть запрос HTTP GET. Таким образом, клиент сразу же приступает к отправке запросов уровня приложения. В случае, если сервер успешно принял соединение, он отвечает сообщением ServerHello и другими сообщениями (Certificate и т.д.), заключает фазу открытия сессии сообщением Finished, и сразу же отправляет полезные данные, являющиеся ответом на запрос приложения клиента. Схема полностью вписывается в логику протокола клиент-сервер и, как нетрудно заметить, не содержит каких-то дополнительных двухсторонних транзакций: клиент отправляет запрос и получает ответ, при этои и запрос, и ответ как бы обёрнуты в сообщения TLS, позволяющие попутно установить соединение. Типовой клиентский запрос в схеме 0-RTT не обладает прогрессивной секретностью (PFS), так как использует долговременный ключ, заведомо полученный в другом сеансе. Но после того, как по сокращённой схеме установлено новое TLS-соединение, узлы переходят на сессионные ключи, которые уже могут быть сгенерированы с обеспечением прогрессивной секретности. Тем не менее, схема 0-RTT в целом считается менее безопасной (это отмечено в спецификации TLS).

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

Режим аутентифицированного шифрования (со связанными данными) обозначается AEAD - от англ. Authenticated Encryption with Associated Data. Основной особенностью данного режима является то, что он объединяет, собственно, процедуру зашифрования с процедурой вычисления кода аутентификации (имитовставки) в единый алгоритм. Объединение касается и обратного преобразования: расшифрования. AEAD предусматривает включение в состав входного потока части данных, которые передаются в открытом виде. Эти данные не зашифровываются, но защищается их целостность, так как код аутентификации вычисляется для всего набора данных.

При использовании режимов шифрования, не относящихся к AEAD, например, CBC (Cipher Block Chaining), аутентификация полученных данных проводится при помощи дополнительного алгоритма, в TLS это HMAC, позволяющий определить, что данные не подверглись изменениями. Однако логически, контроль целостности и само шифрование давно представляют единый инструмент защиты информации: на практике, шифрование без аутентификации не имеет смысла. При этом простое объединение двух независимых криптографических примитивов (шифр и алгоритм вычисления имитовставки) в TLS нередко приводило к появлению дополнительных векторов атак. Например, в TLS до версии 1.2 реализация связки CBC и HMAC послужила базой для атаки CVE-2011-3389 (BEAST и пр.) и ряда других атак, которые успешно использовали возможную подмену и перестановку блоков для раскрытия части шифротекста, применительно к HTTP-запросам. (Атаки на TLS более подробно рассмотрены в описании TLS.) AEAD данных проблем не имеет.

Строгое переопределение шифронаборов привело к тому, что, несмотря на одинаковый состав криптографических примитивов, шифронаборы TLS 1.2 - не могут быть использованы для TLS 1.3, и наоборот. То есть, "соседние" по номеру версии TLS полностью не совместимы между собой не только по алгоритмам установления соединения, но и на самом фундаментальном уровне - по шифронаборам. Спецификация TLS 1.3 содержит очень узкий набор рекомендованных криптопримитивов для защиты потока данных: допущено только два шифра - AES и ChaCha20, - и две хеш-функции - SHA-256 и SHA-384. В качестве AEAD-режимов для блочного шифра AES указаны тоже только два варианта: GCM и CCM (это модифицированные режимы счётчика). В случае с AEAD-режимами, минимально возможное число вариантов имеет довольно разумное объяснение: других столь же хорошо проверенных и поддерживаемых распространёнными библиотеками режимов, кроме двух описанных, просто нет. GCM в связке с AES сейчас является фактически единственным, по объёмам трафика, применяемым AEAD-режимом блочных шифров в TLS. При этом режим GCM может использоваться с любым шифром подходящей разрядности, однако типовым шифром для этого режима традиционно является AES и только он входит в список рекомендованных спецификацией TLS 1.3 блочных шифров. Шифр ChaCha20 является потоковым, а аутентификация при его использовании обеспечивается алгоритмом Poly1305. Пара ChaCha20-Poly1305 также является стандартным сочетанием. Теоретически, шифронаборы могут быть добавлены в TLS 1.3 позднее. Помимо AES и ChaCha20, существуют другие добротные шифры, например, российский шифр "Кузнечик" (ГОСТ Р 34.12-2015). Тем не менее, в текущей редакции спецификация TLS 1.3 создаёт трудности для внедрения национальных криптографических стандартов в этот протокол. Так, для российских шифров пока не выработан режим аутентифицированного шифрования, а использование GCM хоть и возможно напрямую, но не является допустимым с точки зрения процедур стандартизации.

Интересно, что спецификация предусматривает (раздел D.4), при необходимости, некоторую имитацию установления соединения TLS 1.2. Это сделано для того, чтобы промежуточные узлы, инспектирующие трафик, пропускали соединения TLS 1.3, принимая их, по сигнатуре, за 1.2. Для этого в ход Handshake вводятся фиктивные сигналы ChangeCipherSpec и другие.

Версия 1.3 исключает использование схемы получения общего секрета при помощи шифрования RSA - Static RSA. Эта схема состоит в следующем. Криптосистема RSA позволяет зашифровывать данные, используя открытый ключ получателя. В TLS предыдущих версий, при использовании Static RSA, клиент генерирует некоторое случайное значение и передаёт его серверу, воспользовавшись открытым ключом RSA из серверного TLS-сертификата. Данная схема довольно давно отнесена в разряд не рекомендуемых, так как не обладает свойством, обычно называемым прогрессивной секретностью (PFS - Perfect Forward Secrecy). Это означает, что если третья сторона записывает TLS-сессии, и этой третьей стороне позже станет известен секретный ключ из пары RSA (то есть, ключ от серверного сертификата, этот ключ является долговременным), то она сможет расшифровать переданный клиентом секрет из записанного трафика и, таким образом, получить сеансовые ключи и расшифровать всю сессию. Использование протокола Диффи-Хеллмана в такой ситуации не позволяет раскрыть сеансовые ключи, так как ключи RSA используются только для генерации и проверки подписи на параметрах DH. Static RSA для TLS очень часто (можно сказать, повсеместно) используется корпоративными системами инспекции трафика. Помимо того, что такая ситуация сложилась исторически, использование именно RSA связано с относительной простотой настройки систем: достаточно дать инспектирующим узлам доступ к секретному серверному ключу RSA, и они смогут на лету получать симметричные сеансовые ключи для TLS-сессии.

История Static RSA в TLS 1.3 получилась довольно насыщенной. Схему исключили практически сразу, в самом начале обсуждения протокола в рабочей группе IETF. Фактически, сходные идеи прямо следуют из RFC 7258, опубликованного ещё в 2014 году. Тем не менее, через некоторое время в рабочую группу TLS поступили сообщения от представителей "банковской сферы", которые просили вернуть Static RSA, мотивируя просьбу тем, что уже существует инфраструктура анализа TLS-трафика, настроенная именно под Static RSA. Внедрение новой версии приведёт к тому, что вся эта инфраструктура перестанет работать. Возникла жаркая дискуссия, продолжавшаяся, в разных форматах, более года, но схема со статическим RSA была отвергнута. Ситуации даже посвящён обстоятельный обзор, опубликованный в блоге IETF. Надо отметить, что инспектирование трафика, при условии согласия одной из сторон соединения, возможно и в случае TLS 1.3. Есть несколько вариантов реализации. Например, сервер может использовать "статический DH", в протоколе Диффи-Хеллмана также есть открытый ключ и его можно зафиксировать, передав копию инспектирующему устройству. У данного метода, впрочем, есть существенный недостаток: использование "статического DH" в современной Сети является аномалией, соответственно, его легко обнаружить, что сразу демаскирует узлы, использующие инспектирование трафика. Но возможны варианты с центральным распределением, на стороне сервера, симметричных сеансовых ключей, либо с передачей копии симметричных серверных ключей инспектирующему устройству. Все эти решения требуют замены оборудования, так как высокопроизводительные системы DPI (инспекции трафика) представляют собой отдельные программно-аппаратные комплексы. Можно по-разному относиться к такому явлению, как инспектирование трафика интернет-сервисов, но одно бесспорно: массовое внедрение TLS 1.3 действительно создаст заметные проблемы существующей инфраструктуре, выполняющей такое инспектирование. Тем не менее, эти проблемы вполне преодолимы: на то, чтобы стать какой-то панацеей, спецификация TLS 1.3 не претендует.

Александр Венедюхин

27/03/2018