Неочевидные особенности веб-TLS в Интернете. Посмотрим на сертификат узла dxdt.ru, а точнее на разные таймстемпы, присутствующие в этом сертификате, выпущенном удостоверяющим центром (УЦ) Let’s Encrypt. Так, время в SCT-метках: Sep 4 20:35:05 2024 GMT (миллисекунды я не указываю), а начальная граница интервала валидности сертификата: Sep 4 19:36:35 2024 GMT. То есть, время меток позже почти ровно на один час. Как такое могло бы получиться? Естественно, вариант тут только один: УЦ Let’s Encrypt выпускает сертификаты, сдвинув время начала действия на час назад. То есть, что называется, “задним числом” (backdate), но только на один час. Реальное время заказа сертификата ближе к таймстемпу из SCT-метки – понятно, что данный УЦ не мог ждать один час, чтобы отправить пресертификат в лог. Тем не менее, это означает, что сертификат “действовал” за час до того, как его заказали.

Это известная особенность, неоднократно упоминавшаяся в обращениях в Let’s Encrypt. Её традиционно объясняют необходимостью учитывать возможные неточности часов у клиентов: то есть, сертификат выпускается за секунды и должен заработать мгновенно, но если у клиентского компьютера отстают часы, то он покажет ошибку, так как в сертификате время стоит позже момента валидации по “сдвинутым часам”.

Почему достаточно одно часа? Не ясно. Возможно, из-за летнего/зимнего времени. Возможно, из-за того, что в 60 минут укладывается бо́льшая часть обычного “дрейфа” локальных часов (она, конечно, укладывается минут в двадцать, но почему бы не взять один час?).

Как это коррелирует с тем, что в SCT-метке всё равно стоит актуальное время, которое оказывается “в будущем” и валидатор всё равно мог бы заругаться? Ну, наверное, эффект остался с тех пор, когда никакие SCT-метки в сертификаты не ставились, к тому же, опережение на час находится в допустимом интервале и валидаторы браузеров не пугает: лишь бы подписи сходились.

Означает ли это, что Let’s Encrypt выпускает пресертификаты (для добавления в CT-лог) “с упреждением”? Вряд ли. Но проверить это нельзя: технически, УЦ может какие угодно сертификаты у себя штамповать, на то он и УЦ. Выпуск пресертификата без факта его заказа и подтверждения прав управления DNS-именем – будет являться грубейшим нарушением принятых правил, но (пре)сертификат ещё должен утечь. Тем не менее, какого-то смысла в подобных фокусах не просматривается.

Вообще, даже и выпуск сертификатов “задним числом” – довольно серьёзное нарушение для УЦ: в своё время именно его использовали в качестве одной из причин для отзыва доверия браузеров к некоторому китайскому УЦ. Но, наверное, один час – это не так много. Обратите внимание на то, что в сертификатах нет никакого зонирования времени, там просто таймстемп, – в случае с CT-логами – миллисекундный, – поэтому списать данную особенность на разные часовые пояса не получится.



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

Пишут, что некоторые роботы-пылесосы собирают данные о помещении, включая фотографии и звукозаписи, и отправляют на центральный сервер поставщика, “для обучения ИИ”. Процитирую свою записку-лирическое отступление из 2016 года:

“– Никогда не доверяй пылесосам, – пробормотал Винсент, – особенно, если это пылесос-инсайдер”.



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

Немного про разные подставные URL/URI, используемые в целевых рассылках по электронной почте (имитирующих “запрос на смену пароля”, “просмотр заказа” или ещё что-то), а также в других подобных инструментах. Такие ссылки, как известно, могут вести совсем не туда, “куда написано”, или почти туда, но, всё же, не совсем – последнее актуально для корпоративных сред. Помимо подмены DNS и прочих внешних действий, у самих ссылок есть некоторые занимательные признаки, повышающие “степень подозрительности”.

Понятно, что современные почтовые клиенты позволяют замаскировать реальную ссылку многими способами, начиная от простой замены с использованием HTML и вплоть до изящных трюков с CSS, спецсимволами, сочетаниями букв, которые похожи по начертанию на “настоящее имя”, с картинками и Punycode. Бывает, что ссылка отображается верно, но выглядит от этого только подозрительнее. Простой признак: какое-то странное “цифровое” имя – site-11.test.ru. (Здесь test.ru выбрано вместо того или иного “корпоративного” домена.) Очень редко использование разных “технических хостнеймов” может быть тут уместным. Скорее – это просто случайный взломанный узел в корпоративной сети: используется то имя, которое досталось, то есть, было присвоено ранее, возможно, автоматически.

Открытый протокол HTTP (http://), если его использование вообще возможно, тоже добавляет баллы подозрительности. Если ссылка указывает на http://example.com/api/123/, то это вовсе и не означает, что, при клике, она поведёт браузер на настоящий узел под example.com. И речь даже не про подмену DNS. Запрос с протоколом HTTP – то есть, направляемый в открытом виде, – может быть перехвачен и перенаправлен на промежуточном узле. Скажем, взломан либо сам этот промежуточный узел (читай – “роутер”), либо, через ту или иную атаку с подменой сетевых маршрутов, трафик конкретной атакуемой рабочей станции может быть перенаправлен в направлении нужного узла (иногда это может делаться при помощи атаки на уровне клиента VPN). Понятно, что при таком перенаправлении перехватить можно любые запросы, однако, если используется TLS/HTTPS, то защищённый трафик ещё нужно раскрыть, что довольно трудно, да и аккуратная подмена открытых запросов требует более изящного подхода – поэтому прочий трафик, не с заданным в ссылке хостнеймом, будет переправляться к месту назначения без изменений.

Отдельный характерный момент, про который часто забывают, – непривилегированный номер порта. Если в ссылке указано example.com:7788 (то есть, на порт с номером 7788, больше 1000), то это может свидетельствовать о том, что трафик будет принимать какое-то приложение, запущенное с правами обычного пользователя. Другими словами: на каком-то произвольном сервере в локальной сети подсажена программа с правами непривилегированного пользователя, сервер имеет имя в локальном DNS-сервисе – всё, можно принимать трафик по HTTP. Можно и по HTTPS, если удалось получить подходящий TLS-сертификат, однако с сертификатом всё несколько сложнее.



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

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

Другими словами, если у вас есть добротный анализатор для языка Fortran (для языка, не для алгоритмов), то он вовсе не обязательно эффективен для программ на Haskell, которые транслированы (ну, предположим) в код на Fortran: проверяться всё равно будет Fortran-программа. Это сильно сужает возможности по созданию полезных универсальных “анализаторов кода на ЯВУ”.

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

Предположим, что на процессоре “Имярек-7” команда MOV (“копирующая/перемещающая какие-то данные”) не просто сама по себе Тьюринг-полная (как в x86), но ещё и содержит “особенность” реализации, приводящую к тому, что число 0xFFFFFFFF превращается в 0x0, если сделать два MOV подряд из ОЗУ в регистр REG1. Поэтому, чтобы какие-то детали гарантировать относительно программы и реализации алгоритма, нужно в рассмотрение включить и аппаратные особенности. Сделать это автоматическим способом непросто. Отчасти поэтому-то и появляются всякие разные трансляции в “байт-код”, пригодный для исполнения “песочницей” (например, “Java-машиной”, если хотите): в такой конфигурации можно построить какие-то формальные описания и для языка, и для “машины”, которая его интерпретирует. Можно показать, что тут, при следовании некоторым принципам, всё разрабатывается безопасно (и это, действительно, так, но далеко не в общем случае).

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

Представьте, что сложную схему отношений между записями алгоритмов, разными языками высокого уровня, компиляторами и аппаратурой зарисовали в виде графа, где направленные рёбра – это стрелки, обозначающие преобразование кода. Например, перевод с одного ЯВУ на другой. Или перевод в машинный код. Или перевод в подмножество состояний конечного автомата, соответствующего процессору. Тут за каждой стрелкой скрываются целые наборы “схлопывающих” и забывающих отображений, при которых различные способы представлений на стороне начального узла все переводятся в единственный способ на стороне узла конечного (такое вот “ядро” отображения). Например, циклы for, while, do – все схлопываются в сочетание операторов if, потому что только так позволяет записывать целевой язык. Тогда базовые логические преобразования, записываемые формально, могут и совпадать, но вот большое количество возможностей по внесению особенностей и ошибок в исходный код – останется вне пределов доступности для того или иного анализатора, схлопнувшись, что называется, до неразличимости.



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

В “Яндекс-картах” запустили сервис “Геоаналитика”. Сообщают, что будут визуализировать “автомобильный и пешеходный трафик”, вместе с социально-демографическими данными, сведения о “поисковых запросах” и “насыщенности различными типами бизнесов” с геолокацией.

В 2013 году (да и раньше) я писал о том, что “Яндекс.Метрика”, установленная на “коммерческом сайте”, предоставляет “Яндексу” данные, которые потом используются платформой интернет-рекламы, чтобы показывать пользователям сайта очень точно подобранные рекламные объявления конкурентов. Сейчас времена поменялись, а технологии развились.

Понятно, что тут уже никакой “Яндекс.Метрикой” на сайте не отделаться: географические данные для “Яндекса” собирают многочисленные пользователи мобильных приложений и прочих сервисов в смартфоне (подключены и курьерские службы, и такси, и т.д.). Зато хорошо видно, в каком объёме и какие сведения можно собирать при таком масштабе: не ясно, всё ли новый сервис “Яндекса” выводит из данных, которые там собираются, но нетрудно предположить, что собирается гораздо больше, поскольку задачи должны бы быть шире, чем запуск некоторой публичной геоаналитики. По крайней мере, потенциально – шире.



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

Иногда при отладке программ требуется просматривать трафик, защищённый TLS. Распространённый случай – HTTPS. Чтобы просматривать содержание TLS-трафика при помощи анализаторов протоколов (Wireshark) нужны сессионные ключи. В этой записке посмотрим, с примерами кода, как экспортировать эти ключи, если используется типовая библиотека Go crypto/tls.

Принцип довольно простой: при установлении TLS-соединения библиотека будет выводить сеансовые симметричные секреты и сопроводительный параметр (поле Random) в заданный файл, который позже использует Wireshark (или tshark, как в примерах ниже) для раскрытия трафика. Чтобы это заработало в Go, достаточно в структуре конфигурации TLS-клиента (или TLS-сервера) указать (KeyLogWriter) имя интерфейса для записи в файл (writer в терминологии Go), а сам интерфейс предварительно создать и направить вывод в нужный файл. А именно (ниже будет рабочий пример кода; здесь – фрагмент):

SessionKeysFile, err := os.OpenFile("s-keys.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
[...]
}
[...]
TLSConfig.KeyLogWriter = SessionKeysFile

Так сконфигурированный экземпляр TLS-соединения (в смысле кода Go) будет писать в заданный файл s-keys.txt сведения о ключах, в текстовом формате. Сам формат очень простой, но отличается для TLS 1.3 и других версий (см. ниже). Полный пример работающего кода для TLS-клиента (логика кода экспорта ключей для сервера – не отличается):

package main

import (
	"fmt"
	"net"
	"time"
	"crypto/tls"
	"os"
)

func main(){
	var TLSConfig tls.Config
	SessionKeysFile, err := os.OpenFile("s-keys.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		fmt.Printf("File error: %s\n", err.Error())
		os.Exit(1) 
	}
	hostname := "example.com"

	TLSConfig.KeyLogWriter = SessionKeysFile
	TLSConfig.MinVersion = tls.VersionTLS13
	TLSConfig.MaxVersion = tls.VersionTLS13
	TLSConfig.RootCAs = nil
	TLSConfig.InsecureSkipVerify = true

	timeout := 3 * time.Second
	TCPConn, err := net.DialTimeout("tcp", hostname + ":443", timeout)
	if err != nil {
		fmt.Printf("Connection error: %s\n", err.Error())
		os.Exit(1)
	}

	TCPConn.SetReadDeadline(time.Now().Add(timeout))
	TCPConn.SetWriteDeadline(time.Now().Add(timeout))

	TLSConn := tls.Client(TCPConn, &TLSConfig)

	HTTPGet := "GET / HTTP/1.1\r\nHost: " + 
				hostname + "\r\n" + 
				"Connection: close\r\n" +
				"User-Agent: TLS-keys-dump" + 
				"\r\n\r\n"
				
	_, err = TLSConn.Write([]byte(HTTPGet))
	if err != nil {
		fmt.Printf("Connection (TLS) write error: %s\n", err.Error())
		TLSConn.Close()
		os.Exit(1)
	}
	TLSConn.Close()
	os.Exit(0)
}

Используя привычные многим tcpdump и tshark нетрудно посмотреть, что получилось. В tshark файл с сессионными секретами передаётся при помощи опции tls.keylog_file (в Wireshark – можно загрузить через интерфейс редактирования параметров TLS-парсера). Вызов tshark:

$ tshark -r dump-ens.pcap -o tls.keylog_file:tls-export-keys/s-keys.txt -O tls -S "-----PACKET-----" -x

Здесь: dump-ens.pcap – дамп трафика, записанный tcpdump; s-keys.txt – файл, в который экспортированы TLS-секреты.
Фрагмент результата работы:

Decrypted TLS (83 bytes):
0000  47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a   GET / HTTP/1.1..
0010  48 6f 73 74 3a 20 65 78 61 6d 70 6c 65 2e 63 6f   Host: example.co
0020  6d 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63   m..Connection: c
0030  6c 6f 73 65 0d 0a 55 73 65 72 2d 41 67 65 6e 74   lose..User-Agent
0040  3a 20 54 4c 53 2d 6b 65 79 73 2d 64 75 6d 70 0d   : TLS-keys-dump.
0050  0a 0d 0a

Обратите, кстати, внимание на то, что в TLS 1.3 без секретных ключей сессии не удалось бы посмотреть даже серверные сертификаты. Так что, вообще говоря, для того, чтобы убедится в работоспособности метода, можно было бы даже и не отправлять GET-запрос HTTP, как написано в коде выше: для минимальной проверки в TLS 1.3 достаточно сразу разорвать TLS-соединение, при этом факт успешной записи части сессионных ключей в файл отразится в том, что tshark смог разобрать TLS-сертификаты, присланные сервером. Другое дело, что в TLS 1.3 для зашифрования сертификатов используются другие ключи, не те, что для защиты трафика (см. ниже).

Почему это работает? Прежде всего потому, что в TLS для защиты трафика в рамках сессии используются симметричные шифры и, соответственно, симметричный набор секретов для получения не менее симметричных секретных ключей. Так что для расшифрования не нужно получать “ключи сервера” или “ключи от сертификата сервера”. Симметричных ключей используется пара: один для отправки данных, второй – для получения (на клиенте и сервере эти ключи меняются местами). Соответственно, если анализатор трафика знает симметричные ключи, то он может расшифровать записанный трафик. Посмотрим, какой формат у файла с экспортированными ключами. Для TLS 1.3:

CLIENT_HANDSHAKE_TRAFFIC_SECRET [%RANDOM%] [%SECRET%]
SERVER_HANDSHAKE_TRAFFIC_SECRET [%RANDOM%] [%SECRET%]
CLIENT_TRAFFIC_SECRET_0 [%RANDOM%] [%SECRET%]
SERVER_TRAFFIC_SECRET_0 [%RANDOM%] [%SECRET%]

Чтобы не перегружать текст шестнадцатеричными цифрами я заменил поля, содержащие соответствующие данные, на понятные имена: [%RANDOM%] и [%SECRET%]. В исходном файле, очевидно, на месте этих обозначений будут длинные наборы шестнадцатеричных цифр.

В поле с именем [%RANDOM%] записывается значение из поля Random начального сообщения ClientHello. Это может показаться загадочным, если вы не сталкивались с TLS ранее, однако тут данное значение нужно лишь для того, чтобы анализатор протокола мог быстро сопоставить конкретный секрет и конкретную TLS-сессию в записанном трафике: то есть, в данном случае, это всего лишь метка. Сам секрет, позволяющий получить ключи для шифров, указывается в поле [%SECRET%]. (Ключи вычисляются на основе данного секрета при помощи соответствующей функции HKDF.)

В файле указаны клиентские и серверные секреты для разных этапов соединения TLS 1.3. CLIENT(SERVER)_HANDSHAKE_TRAFFIC_SECRET – это ключи для защиты начальных сообщений. CLIENT(SERVER)_TRAFFIC_SECRET_0 – это ключи первого поколения для защиты трафика. В TLS 1.3 возможно обновление ключей в рамках сессии, то есть, могли бы быть и TRAFFIC_SECRET_n следующих поколений, но это тема для другой записки. Формат файла подразумевает и другие поля, которые тоже тут не рассматриваются – все они устроены так же, но сдержат секреты других типов, которые могут появиться в ходе соединения TLS 1.3, так что анализаторы трафика должны обрабатывать их автоматически.

Для TLS 1.2 файл с экспортируемыми секретами, генерируемый библиотекой Go, будет будет использовать другой формат:

CLIENT_RANDOM [%RANDOM%] [%SECRET%]

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

***

Некоторые другие записки по этой же теме:

TLS для DevOps
Секретные ключи в трафике и симметричные шифры
TLS в виртуальных машинах и извлечение ключей хостингом

Технические детали устройства TLS – можно узнать в техническом описании.



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

Интересный практический пример неверной настройки DNS в зоне vk.com, как его можно видеть и сейчас, и уже в течение нескольких недель. Скриншот выдачи сервиса проверки audit.statdom.ru (подробные объяснения – ниже):

DNS vk.com

Зона vk.com делегирована на авторитативные NS с именами, находящимися в той же зоне (так называемые “субординатные” NS), а именно: ns1, ns2, ns3, ns4.vk.com (всё в vk.com, не лучшее решение, но сейчас о другом). При этом в самой зоне vk.com для имён NS указаны AAAA-записи – это DNS-записи, содержащие IPv6-адреса. Вообще, чтобы избежать циклов при рекурсивном опросе DNS, для имён авторитативных серверов, которые сами определены в делегируемой зоне, используются так называемые glue-записи: серверы имён вышестоящей зоны возвращают IP-адреса для имён, на которые эта зона делегирована.

То есть, если домен example.com делегирован на ns1.example.com и ns2.example.com, то авторитативные серверы зоны первого уровня com. будут возвращать в дополнительном блоке DNS-ответа IP-адреса для ns1.example.com и ns2.example.com, чтобы резолвер мог к ним обратиться. (Понятно, что иначе резолвер, для определения адреса ns1.example.com, должен обратиться к DNS-серверам example.com, а чтобы обратиться к DNS-серверам example.com – нужно узнать адрес ns1.example.com, ну и так далее.)

Так вот, для vk.com в glue- указаны только А-записи (IPv4-адреса), но не указаны AAAA-записи (IPv6-адреса). Между тем, как отмечено в предыдущем параграфе, в самой зоне IPv6-адреса для NS указаны: каждый NS из списка делегирования снабжён v6-адресом в DNS. Под “данными в самой зоне” тут имеются в виду данные, возвращаемые непосредственно авторитативными NSами (которые ns[1,2,3,4].vk.com).

Вообще говоря, делегирующие ответы – и, тем более, glue-записи – имеют ключевое значение на базовой стадии рекурсивного опроса, но состав записей для NS в самой зоне может быть другим, при условии, что сведения, полученные с серверов уровнем выше, в этот состав вкладываются. То есть, можно допустить, что в самой зоне указаны дополнительные NS, которых нет в списке делегирования (обратная ситуация свидетельствует об очень грубой ошибке и представляет собой угрозу).

Для vk.com дополнительными оказываются адреса IPv6 для авторитативных NS. Адреса выбраны красивые, резолверы, работающие по v6, могли бы их использовать, но DNS-сервис под ними недоступен и отсутствуют glue-записи.



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

Гибридная криптосистема с постквантовой стойкостью X25519Kyber768 использует, как нетрудно догадаться, ключи X25519 в дополнение к Kyber. При этом X25519 – типовая криптосистема в современном TLS, так что в одном и том же ClientHello может быть одновременно два ключа: и X25519Kyber768, и просто X25519. И вот, например, Firefox в свежих версиях использует тут один и тот же ключ X25519 – и в гибриде, и в обособленном варианте. Это экономит одну итерацию X25519 (технически, что в гибридном варианте, что нет – это одна и та же криптосистема, никаких отличий). А вот Chrome, в такой же ситуации, использует два разных ключа X25519.



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

Снова пишут о том, что пользователи TOR могут быть “деанонимизированы” при помощи анализа параметров трафика с сопоставлением по времени. Почему-то, иногда такая особенность преподносится как новость. Но это весьма старый метод. Например, я писал об этом почти десять лет назад на dxdt.ru:

Внутри сети TOR пользовательский трафик зашифрован, “вложенным” шифрованием. Известно, что параллельный анализ трафика, наблюдаемого на входном и выходном узлах (то есть, трафика, входящего в TOR и выходящего из этой сети), позволяет деанонимизировать источник трафика.

P.S. В той записке есть ссылки на два внешних ресурса: PDF с исходным описанием на сайте издания Spiegel и ссылка на сайт журнала “Доменные имена”, в котором я публиковал статью по теме. Показательно, что ни одна из ссылок нынче не ведёт на документы и тексты: обращение по адресу на сайте издания Spiegel – возвращает HTTP 404, а ссылка на сайт “Доменных имён” – переадресует на главную страницу nic.ru. В последнем случае, это связано с тем, что RU-CENTER вообще удалил сайт журнала – мне до сих пор непонятно по какой такой причине, поскольку, хоть сам журнал и закрыли, но на сайте был весьма полезный архив номеров.



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

Использование имеющихся сейчас посквантовых криптосистем в TLS существенно увеличивает объём передаваемых данных. Например, ключ Kyber768, используемый в первом же сообщении (ClientHello), требует более килобайта (1184 байта). При этом, в TLS 1.3 есть штатная возможность передать несколько ключей для разных криптосистем в одном сообщении ClientHello, чтобы сервер выбрал подходящее. Эта возможность постоянно используется на практике.

Например, клиент может сразу передать ключи X25519 (32 байта) и P-256 (32+32 == 64 байта). То есть, две криптосистемы – и лишь 96 байтов расходуется на запись ключей (небольшое количество дополнительных байтов нужно для записи тех структур, в которых передаются ключи, но это можно не учитывать). Если передавать ключи двух постквантовых криптосистем, – скажем, с теми же Kyber768 и стандартизованным вариантом ML-KEM, – то получается уже больше двух килобайт. Это много, но если регулярно переходить от одной поствкантовой криптосистемы к другой, то становится необходимым, рутинным элементом TLS-соединений. Заметьте, что сам перечень поддерживаемых клиентом криптосистем для обмена сессионными секретами передаётся в TLS отдельно. Обычно, в этом перечне указано значительно больше криптосистем, чем передано ключей. Так, браузер может передавать семь поддерживаемых вариантов и ключи только для трёх из них (так сейчас делает Firefox). Чтобы сервер мог выбрать криптосистему, ключи от которой отсутствуют в ClientHello, в TLS 1.3 предусмотрен механизм повторного согласования – HelloRetryRequest: сервер, в этом случае, запрашивает повторное ClientHello, где будет только ключ той криптосистемы, которая выбрана (это всё можно самостоятельно увидеть на тестовом сервере TLS 1.3 при помощи современного браузера).

Подобный перебор с постквантовыми криптосистемами ещё больше увеличивает трафик, поэтому уже рассматриваются варианты того, как бы данный момент переложить на DNS. Так, в сообщении Google про ML-KEM в браузере Chrome, на которое я недавно ссылался, упоминается соответствующий черновик RFC – там предлагается публиковать в DNS сведения о предпочитаемых криптосистемах для обмена сеансовыми ключами в TLS. Конечно, тут нужно учитывать возможную защиту DNS-ответов от подмены, то есть, всё это тянет за собой не только и не столько DNSSEC (которая сама не имеет пока что ничего “постквантового”), как DNS-over-TLS/DNS-over-HTTPS.

Развитие постквантового TLS очень бурное. Впрочем, пока что не совсем понятно, для чего вообще такой рост объёмов данных. Сама по себе “постквантовая стойкость” тут ничего не объясняет, как и популярные описания в стиле “зашифруй заранее, пока нет квантового компьютера”. Однако вот уже и DNS охвачена дополнением записей. С одной стороны, размещение предварительных сведений о настройках TLS в DNS выглядит более чем разумно: запрос в систему всё равно необходим для получения IP-адреса; с другой стороны – данное направление развития как-то быстро сводится к надстраиванию новых и новых, всё больших и больших “дополнений”. (Надстраивание происходит в ускоряющемся темпе: не успели год назад внедрить в браузеры Kyber, как его уже переименовали в ML-KEM и переделали.) Эти “дополнения” вытесняют привычную работу с DNS, заменяя её на другой процесс, который следует называть “обнаружением сервисов” (Service Discovery) – дело в том, что с появлением ECH даже и IP-адреса будут извлекаться из доступной сети по-другому.



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

Google пишет, что в ближайших версиях Chrome отключит использование Kyber768, заменив его на ML-KEM. Речь про использование в гибридной криптосистеме с постквантовой стойкостью для обмена ключами TLS 1.3. То есть, вместо X25519+Kyber768 будет ML-KEM+X25519 (здесь “минус” это дефис, а “плюс” – это плюс). Связано решение с тем, что криптосистему, в постквантовой части, стандартизировал NIST, и вариант из стандарта (кто бы мог подумать!) не совместим с тем вариантом, который использовался до стандартизации под именем Kyber.

В частности, при стандартизации отказались от одного из “промежуточных” преобразований с хеш-функцией, которое, в теории, могло бы предотвращать утечки состояния генератора (псевдо)случайных чисел. Про это всё, естественно, написано в документе NIST. Формулировка выглядит занимательно для тех, кто следит за темой модификации криптосистем в стандартах. В цитате далее (из приложения к стандарту NIST) под словосочетанием “этот шаг” (this step) имеется в виду шаг алгоритма, на котором вычислялось значение SHA-256 от инициализирующего значения: “The purpose of this step was to safeguard against the use of flawed randomness generation processes. As this standard requires the use of NIST-approved randomness generation, this step is unnecessary and is not performed in ML-KEM”. Пересказ смысла: поскольку в стандарте NIST прописано требование использовать только генераторы случайных чисел, разрешённые NIST, то и дополнительная защита от “испорченных генераторов” (то есть, оборачивание значения в хеш-функцию) более и не требуется. Логично, чего уж там. Строго говоря, ничто не мешает применить хеш-функцию для маскировки состояния раньше, до передачи значения в KEM. (Тут, конечно, речь только про дополнительный шаг уровня реализации, а SHA-3, требуемая непосредственно внутри Kyber, осталась.)

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



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