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

То есть, особенность ESNI в том, что в качестве дополнительного источника ключей, защищающих метаинформацию, используется независимая от TLS система – DNS. Это важный момент: для того, чтобы зашифровать “адрес обращения”, клиенту не нужно устанавливать дополнительные соединения – получить нужный ключ можно типовым запросом к системе доменных имён; вообще говоря, не обязательно при этом указывать имя того TLS-узла, с которым будет соединяться клиент.

Провайдер хостинга может использовать ключи, опубликованные под одним DNS-именем, для обеспечения доступа к “скрытым серверам” под совсем другими именами, это означает, что открытый запрос в DNS не будет раскрывать имя “целевого узла”. Например, Cloudflare сейчас использует одни и те же ключи для самых разных веб-узлов. Более того, “скрытый узел” может находиться за некоторым “фронтэндом”, имеющим другое, универсальное, имя – фактически, это Domain Fronting.

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

В открытой DNS, системы анализа трафика, которые видят весь трафик клиента, могут сопоставить запрос в DNS для извлечения ключа ESNI и последующее TLS-соединение. DNS-ответ с ключами даже можно заблокировать, сделав использование ESNI невозможным (но только при условии, что ключи не были получены другим способом). Однако автоматическое корректное сопоставление имени из DNS-запроса и сессии TLS – представляют серьёзную дополнительную задачу, которая тем сложнее, чем больше объём трафика, анализируемого системой фильтрации. (Конечно, уже само наличие ESNI может являться признаком подозрительного соединения.)

То есть, ESNI, в случае массового внедрения, довольно заметно повлияет на ландшафт систем инспекции трафика. А кроме того, данная технология может подстегнуть рост распространённости DNSSEC и DNS-over-TLS. Впрочем, пока что ESNI не поддерживается распространёнными веб-серверами, да и соответствующий RFC не вышел из статуса черновика.

(Как работает ESNI – можно посмотреть на моём тестовом сервере TLS 1.3, там реализована поддержка.)



Комментарии (2) »

На днях NIST опубликовал результаты первого этапа программы по стандартизации постквантовых криптосистем (распределения ключей и электронной подписи), во второй раунд прошло 26 предложений из 82 поступивших на рассмотрение в самом начале (к первому этапу из них было допущено 69). Это повод очередной раз вспомнить о том, что постквантовые криптосистемы сейчас составляют одно из основных направлений современной криптографии. Постквантовые – это такие криптосистемы, которые устойчивы к взлому с использованием универсального квантового компьютера. Давно известно, что распространённые сейчас асимметричные криптосистемы (RSA, ECDSA, используемые разновидности протокола Диффи-Хеллмана) полностью уязвимы к атакам, использующим квантовые алгоритмы “нахождения периода”, это, в принципе, алгоритм Шора.

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

Скорее всего, на начальном этапе та или иная постквантовая криптосистема будет использоваться параллельно с классической. То есть, результаты обмена ключами по постквантовому алгоритму и по классическому будут смешиваться при генерации симметричных ключей, это обеспечит стойкость в том случае, если постквантовая криптосистема окажется уязвимой для классических атак (такие атаки вполне могут появиться раньше самого квантового компьютера). В браузере Chrome уже проводился эксперимент по использованию постквантовой криптосистемы New Hope.

Думаю, можно предположить, что приняты будут постквантовые криптосистемы, основанные на свойствах эллиптических кривых. Собственно, несколько лет назад я специально разместил на dxdt.ru краткую заметку, на которую можно сослаться, когда процесс выбора криптосистем, как говорится, сойдётся. Заметка даже специфицирует конкретное направление (изогении). Эллиптические кривые хорошо подходят потому, что, во-первых, они являют собой фундаментальную теоретико-числовую структуру, имеющую огромное чисто математическое значение; во-вторых, эллиптические кривые хорошо изучены внутри теоретической криптографии; в-третьих, для них наработано большое число библиотек и прикладных алгоритмов, которые, к тому же, тщательно проверены и оптимизированы. (Эти преимущества перечислены и в публикации NIST.)

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



Комментарии (3) »

Внёс некоторые дополнения на сервер tls13.1d.pw. Во-первых, появилась поддержка “пересогласования” (renegotiation) параметров соединения. В TLS 1.3 есть отдельный механизм, который позволяет серверу запросить у клиента другие параметры протокола Диффи-Хеллмана, конечно, при условии, что клиент их поддерживает. Для этого сервер, в самом начале процесса установления соединения, отправляет сообщение HelloRetryRequest. (Технические подробности есть в описании TLS.) Я давно планировал дописать на сервер поддержку классического варианта протокола Диффи-Хеллмана (DH), который есть в Firefox. Так как по умолчанию браузеры используют эллиптический вариант, включение классического – как раз требует пересогласования параметров. То есть, чтобы заработал классический DH, нужно реализовать пересогласование.

Чуть ранее – я добавил поддержку ESNI. Так вот, в процессе отладки механизма пересогласования выяснилось, что в библиотеке NSS, которая используется Firefox, содержится ошибка в реализации механизма HelloRetryRequest, которая не позволяет использовать вместе с ним ESNI (про ошибку разработчикам я сообщил; вроде, планируют исправить). Так что теперь действие полезного механизма ESNI в Firefox можно наблюдать только в тех случаях, когда сервер не использует пересогласования: для этого нужно обновить страницу tls13.1d.pw несколько раз – группы DH на сервере выбираются псевдослучайным образом, так что, если выбор совпал с перечнем ключей браузера, присланных по умолчанию, то пересогласования не будет, а сработает ESNI.

Соответственно, во-вторых, – это и есть реализация классического DH. Его ещё называют “мультипликативным” вариантом, DH “в конечном поле” и так далее, а если говорить не слишком научно, то это алгоритм в арифметике остатков. Chrome/Chromium поддерживают только эллиптический вариант, соответственно, там увидеть классический никак не удастся. А вот в Firefox – можно. На сервере я реализовал только одну группу, зато самую “большую”: FFDHE3072. В предыдущих версиях TLS – сервер мог выбрать произвольную группу для классического DH, в версии TLS 1.3 список зафиксировали. Я некоторое время назад писал про то, как выбираются параметры для этих групп. По сравнению с эллиптическими вариантами, запись ключа FFDHE3072 – весьма длинная, 384 байта. Вот так результат выглядит на скриншоте:

FFDHE screen

В-третьих, добавил ограниченную поддержку TLS Cookies: она ограниченная потому, что соответствующее расширение передаётся сервером и принимается от клиента, но корректность его использования клиентом пока никак не проверяется. TLS Cookies – это инструмент, позволяющий серверу проверить, что клиент действительно отвечает и намеревается установить TLS-соединение. Особенно полезны, когда используется безсессионный транспорт, как в DTLS.

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



Комментировать »

При установлении TLS-соединения имя узла передаётся в открытом виде, внутри поля (или расширения) SNI – Server Name Indication. На стороне сервера имя узла требуется для того, чтобы выбрать правильный набор сертификатов и серверных ключей, в случае, если на одном IP-адресе отвечает несколько TLS-узлов.

С появлением новой версии TLS 1.3, в которой зашифрована существенная часть сообщений, передаваемых при установлении соединения, вновь обострились споры относительно того, что хорошо бы зашифровать и SNI – ведь через это поле происходит утечка информации о том, с каким именно узлом устанавливается соединение.

Предлагалось несколько вариантов защищённого SNI. Вероятно, будет выбран вариант, использующий ключи в DNS: для него уже есть поддержка в браузере Firefox (версии 64 и Nightly) и на веб-узлах Cloudflare, несмотря на то, что сама спецификация пока в состоянии черновика.

Защищённый вариант называется ESNI (Encrypted SNI) и доступен только для TLS 1.3 (и, в будущем, выше). Рассмотрим, как он работает.

Основная идея следующая. В DNS размещается специальная запись (сейчас это TXT-запись, но, возможно, скоро появится выделенный для ESNI тип), в которой публикуется открытый ключ сервера (для протокола Диффи-Хеллмана (DH), см. ниже) и другие криптографические параметры. А именно: шифронабор, используемый для защиты SNI; группа для DH; контрольная сумма; время действия ключа. Для адресации DNS-записи служит специальное имя, имеющее вид _esni.example.com (здесь важен символ подчёркивания в начале).

Например, для узла tls13.1d.pw имя записи будет таким: _esni.tls13.1d.pw. А значением является структура с криптографическими параметрами, закодированная в Base64. Вот действующее значение для _esni.tls13.1d.pw:

“/wGu7tnmACQAHQAgLukkHH6AiIAPYODmYK/6Nz3H7N58nYZyb/WG62h4TTgAAhMBAIAAAAAAXCPQTgAAAABcQ3ROAAA=”

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

Обычно, клиентом является браузер. Он действует по следующему алгоритму: извлекает из DNS запись, содержащую данные ESNI; используя эти данные, генерирует свою часть обмена по протоколу Диффи-Хеллмана, вычисляет общий секрет, на его основе генерирует симметричный ключ и зашифровывает SNI симметричным шифром. Получившийся шифротекст – передаётся в составе нового расширения сообщения TLS ClientHello ESNI. Вместе с зашифрованным SNI передаётся клиентский ключ DH, который необходим серверу для получения симметричного ключа. Таким образом, третья сторона, прослушивающая канал, не может прочитать значение SNI.

Конкретный пример используемых криптосистем: для (эллиптического) DH используется кривая Curve25519; в качестве шифра – AES в режиме GCM. Все эти параметры, как указано выше, записаны в DNS.

Сервер обнаруживает наличие ESNI по присутствию соответствующего расширения в сообщении ClientHello, отправленном браузером (с этого сообщения начинается процесс установления TLS-соединения). Так как сервер знает секретный ключ DH, он может вычислить общий секрет и симметричный ключ, а после этого – расшифровать имя сервера, полученное в ESNI. Также сервер, успешно обработавший ESNI, отвечает с подтверждением: возвращает клиенту уникальное значение, полученное в зашифрованной части ESNI; при этом значение передаётся в защищённом виде, то есть, получаем ещё один, дополнительный, канал подтверждения подлинности сервера (для клиента).

Очевидно, что в данной схеме имя узла потенциально передаётся в открытом виде при запросе в DNS, поэтому необходимо использовать инструменты защиты DNS-трафика. В частности, в Firefox используют DNS-over-HTTPS (DoH), но данная технология защищает трафик только на “последней миле”, то есть, на пути от рекурсивного резолвера к клиенту. Кроме того, DoH никак не решает проблему подмены DNS-ответов. То есть, в полной мере ESNI заработает только при условии поддержки DNSSEC и внедрения TLS для защиты DNS-транзакций на всех этапах. Тем не менее, с чего-то нужно начать, поэтому внедрение ESNI в распространённый браузер – весьма хороший стимул, который может подтолкнуть и другие технологии.

В качестве теста, я реализовал ESNI, в только что описанной версии, на сервере tls13.1d.pw. Попробовать можно при помощи браузеров Firefox Nightly или Firefox 64. Поддержка ESNI включается в “about:config” (в 64-й версии уже должна быть включена “из коробки”); обязательно нужно также активировать DoH (DNS-over-HTTPS), указав URI сервера, который будет обслуживать DNS-запросы – в Firefox ESNI без DoH не работает.

Если вы зайдёте на tls13.1d.pw с поддержкой ESNI, то информацию об этом сервер выведет в начале страницы – как на скриншоте (update, 10/04/19: ошибку в Firefox исправили, начиная с версии 66.0.2 в основной линейке, так что поддержка ESNI теперь не зависит от пересогласования параметров;update, 05/02/19: из-за ошибки в библиотеке NSS, на которой базируется реализация TLS в Firefox, увидеть при помощи этого браузера ESNI на tls13.1d.pw можно только в том случае, если сервер не использовал пересогласование параметров – то есть, нужно несколько раз обновить страницу; подробнее – в отдельной записке).

Screenshot



Комментарии (1) »

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

Кроме этого, как обычно, актуализировал весь текст, внёс некоторые дополнения в другие разделы.



Комментарии (2) »

Анонимизация больших объёмов данных, которые собирались для конкретных персон, представляет большую проблему. Особенно, если данные достаточно подробные, уникальные и их много. В недавно опубликованной работе исследователи показывают, что публично доступные “анонимизированные” базы “расшифровок” человеческой ДНК, собранные различными проектами, не только оказываются пригодными для эффективной деанонимизации, но ещё и позволяют идентифицировать людей, которые образцов ДНК ни в какой проект не сдавали (но, понятно, где-то такой образец оставили). Данные ДНК могут показаться разрозненными, но это совсем не так, если смотреть на них с точки зрения биологических механизмов. Интересно, что если наложить на набор данных ДНК генеалогические деревья, сопоставив родственников по фрагментам кода, то исходный набор “анонимных” данных тут же теряет всю свою “вариативность”. Если у вас есть база данных с ФИО и отношениями родства, то достаточно подставить в дерево хотя бы одну реальную персону, как все остальные узлы тут же деанонимизируются самым очевидным образом. При неполных данных – всё равно можно уверенно перескакивать между ветками, обнаруживая двоюродную и троюродную родню.

В работе по ссылке – показано, что механизм наследования достаточно силён для того, чтобы покрыть практически всю популяцию, собрав ДНК лишь у небольшой части людей. И речь тут идёт о том, что публичные “анонимизированные” базы позволяют идентифицировать персон, ДНК которых в базе отсутствует, но нашлись родственники разной степени “отдалённости”. Цитата:

“Используя конкретную модель, мы можем предсказать, что база данных с записями о приблизительно 3 млн жителей США европейского происхождения (2% соответствующего взрослого населения), позволяет найти для 99% населения данной этнической принадлежности как минимум одного троюродного родственника, а для 65% – как минимум одного двоюродного”.

Чтобы сопоставить реальных персон записям в базах ДНК, исследователи используют год рождения, примерное место проживания – это позволяет резко улучшить точность. Собственно, задача складывается в чисто комбинаторную, а комбинаторные соображения очень часто помогают убрать всё лишнее и найти реальную структуру, стоящую за данными. Я довольно давно писал на сходную тему, правда, в привязке к “анонимизированным” данным геолокации.



Комментарии (3) »

Новая версия TLS 1.3 получила RFC, а именно – RFC 8446 (обратите внимание: TLS 1.0 – RFC 2246, TLS 1.1 – RFC 4346, 1.2 – RFC 5246). Я уже довольно подробно описывал этот новый протокол, который радикально отличается от всех предыдущих версий TLS/SSL. Вот ссылка на подробную статью про TLS 1.3. В блоге Cloudflare – опубликован хороший популярный обзор TLS 1.3 (но он на английском).



Комментарии (1) »

TLS 1.3 – это новая версия протокола, вот-вот должен появиться RFC (пока что актуален черновик – draft-28). По адресу https://tls13.1d.pw/ я разместил тестовый сервер, который позволяет попробовать TLS 1.3 на практике, при помощи браузера. Поддержка протокола пока есть далеко не везде. Для сервера я полностью написал стек TLS версии 1.3 на Go, то есть, реализовал всё, что “выше TCP”, так как в стандартной библиотеке поддержки 1.3 нет. (Ну, строго говоря, криптопримитивы использованы библиотечные, а именно – шифры и алгоритмы на эллиптических кривых для протокола Диффи-Хеллмана (DH) и электронной подписи ECDSA.) Это именно тестовый сервер, поэтому он поддерживает не все возможности TLS 1.3, но базовые – поддерживает. В частности, я реализовал две draft-версии: 28 и 23. Draft-28 – должен стать RFC, а 23-й поддерживается распространёнными клиентами. (Update: c 09.2018 поддерживается и RFC-версия – 0x0304.) Сервер умеет шифры AES (с GCM) и ChaCha20 (c Poly1305). DH для сеансовых ключей и подпись – только эллиптические (возможно, RSA и “мультипликативный” DH я добавлю позже; update: c 26/01/2019 – есть поддержка “мультипликативного” DH). Кроме TLS – есть кусочек, поддерживающий HTTP-запрос GET, он позволяет использовать обычный браузер и выводит в текстовом виде подробную информацию о TLS-соединении. Понятно, что для получения этой информации TLS-соединение нужно установить. Версий TLS ниже 1.3 – тестовый сервер не поддерживает (совсем не поддерживает: всё же, это специальный сервер, я просто не стал их реализовывать, так как от 1.3 они отличаются весьма существенно).

Два самых распространённых браузера – Chrome и Firefox – уже умеют TLS 1.3 в своих самых свежих версиях. Я проверил Chrome 68 (версия draft-23 TLS) под Debian и Android 8, FireFox Quantum 62.0b14 (это бета) под Debian, а также Firefox 61 под Android 8: все эти браузеры соединяются с тестовым сервером, а FF 62 даже поддерживает draft-28 (самый свежий вариант). То есть, вы можете попробовать подключиться к тестовому серверу, если у вас актуальная версия браузера. Кроме того, 1.3 умеет утилита s_client из пакета OpenSSL версии 1.1.1-pre8, но это тоже бета-версия, которую нужно самостоятельно собирать. Все прочие типичные инструменты (wget, curl и т.д.) – скорее всего TLS 1.3 пока что не умеют (но планируют быстро добавить поддержку).

Если браузер сумел договориться с сервером, то вы увидите простую текстовую страницу (англ.) с параметрами TLS, в частности, там отображаются сеансовые ключи. Сервер использует полноценный TLS-сертификат от Comodo (с ECDSA), поэтому предупреждений о безопасности барузер показывать не должен. Если соединиться не удалось, то, скорее всего, браузер выведет ту или иную ошибку SSL/TLS. Возможны варианты, когда соединение просто сбрасывается на уровне TCP (например потому, что мой сервер не присылает фиктивное сообщение ChangeCipherSpec, и такие соединения разрывает DPI, но это технические детали, которые, впрочем, очень интересно отследить). Попробуйте: https://tls13.1d.pw.

(Сервер специально использует статический ключ DH и “не слишком случайное” значение поля Random.)

Update: кстати, если вы хорошо знакомы с TLS и интересуетесь всякими занимательными “гиковскими” штуками, то рекомендую внимательно взглянуть на открытый ключ ECDSA сервера tls13.1d.pw – этот ключ входит в состав TLS-сертификата (смотреть нужно в шестнадцатеричной записи).

Update 13/08/2018: добавил передачу сообщения ChangeCipherSpec сервером; в случае TLS 1.3 – это фиктивное сообщение, которое нужно только для того, чтобы “замаскировать” TLS-соединение под предыдущие версии, обеспечивая прохождение через промежуточные узлы с DPI и прочей фильтрацией трафика.

Update: c 28/12/2018 добавил поддержку ESNI.

English note: there is a test implementation of TLS 1.3 server (RFC 8846, draft-28,-17) with HTTPS support.



Комментировать »

SNI – это Server Name Indication, поле, которое передаёт клиент на начальном этапе установления TLS-соединения. В данном поле указано имя сервера (на уровне приложений), с которым клиент планирует установить соединение. Например, при обращении к dxdt.ru по HTTPS, ваш браузер указывает в SNI строку dxdt.ru. Указание SNI нужно для того, чтобы на стороне сервера по имени различать “виртуальные хосты” (узлы), которые разделяют общий IP-адрес. Например, если у сервера есть несколько наборов TLS-сертификатов и серверных ключей для разных имён, то на основании SNI он может определить, какие сертификаты передавать в данном TLS-соединении. Сейчас, во всех версиях TLS, включая новейшую 1.3, поле SNI передаётся в открытом виде. Это означает, что прослушивающая канал связи третья сторона может определить имя узла, с которым устанавливается соединение, несмотря на то что TLS использует шифрование для защиты от прослушивания.

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

Тем не менее, решения предлагаются. Скорее всего, значение SNI всё же спрячут. Свежий черновик (draft) RFC предлагает использовать для шифрования SNI записи DNS. Точнее, в DNS предполагается публикация открытого серверного ключа, с помощью которого клиент может зашифровать значение SNI. Такая схема позволяет клиенту сгенерировать нужный ключ заранее, сделав запрос в DNS (сопутствующие параметры публикуются там же, в одной TXT-записи), а сервер сможет расшифровать SNI непосредственно на первой итерации установления соединения (сервер знает секретный ключ). Решение весьма логичное, не требует обмена дополнительными сообщениями, кроме запроса-ответа DNS, который может быть выполнен асинхронно. Предполагается, что публикуемый в DNS ключ относится не к одному конкретному ресурсу, а к сервису, обеспечивающему размещение множества ресурсов.

Фактически, представленная в черновике схема стандартизует Domain Fronting: массовые провайдеры хостинга смогут опубликовать свои ключи для шифрования SNI в DNS, клиенты станут использовать эти ключи для доступа ко всем ресурсам, размещённым у провайдера. Удостоверение подлинности ключей – может быть выполнено в рамках DNSSEC. Ну и следует отметить, что ключи для шифрования SNI могут быть переданы не только через DNS.



Комментарии (3) »
Навигация по запискам: « Позже Раньше »