Docker Hub заблокировал доступ с российских IP-адресов. Последовало множество насмешливых инструкций в стиле “простейшего перехода на зеркала и прокси”. Проблема тут, впрочем, привычная: в практике Docker, в сопутствующих скриптовых обвязках (всякий CI/CD), и так не всё хорошо с аутентификацией источников сборок и самих “контейнеров”. Методы, типа DCT (Docker Content Trust), конечно, есть, это известно. Вопрос в их эффективности и использовании на практике. А прокси и “разбегание” зеркал – тут только добавляют ненадёжных слоёв. Кстати, целевые манипуляции часто удобнее проводить именно с точками выхода прокси и точками входа зеркал (вспомните, как работает разное перемешивание и, скажем, onion routing – тут ситуация обратная).
(Update, 09/06/24: доступ вернули через несколько дней.)
Комментарии (2) »
Кстати, интересуются примером того, как, более или менее конкретно, может что-то сломать сообщение TLS ClientHello от браузера, если в этом сообщении добавлены параметры Kyber768.
Вообще, нетрудно представить следующую ситуацию. Предположим, есть некоторый диспетчер соединений, работающий в паре с пакетным фильтром. Этот фильтр анализирует пакет данных (то есть, последовательность байтов, имеющую конкретную длину) по заданным правилам на уровне значений байтов внутри пакета и расстояний между байтами с заданными значениями. Например, определяет, что пакет представляет собой начало TLS-соединения с некоторыми свойствами и – перенаправляет этот пакет, как и всю сессию, на какой-то заданный входной узел. Этот узел – уже может быть элементом балансировщика трафика, или входить в состав какого-то механизма DPI, предназначенного для борьбы с возможными атаками, или играть какую-то ещё роль. Базовые правила для фильтра позволяют узнавать заявленные версии TLS (это значения полей в сообщении), определять предлагаемые клиентом криптосистемы – всё по значениям байтов на определённых позициях. Скажем, таким способом можно детектировать начало TLS-сеанса с поддержкой ГОСТ-TLS, со стороны клиента, чтобы на стороне сервиса перенаправить соответствующие сессии на сервер, настроенный конкретно для ГОСТ.
Реализация фильтра не только не проводит разбора сессии, но даже не анализирует пакет с ClientHello как содержащий TLS-сообщение ClientHello – фильтр работает только с байтами и их примитивными индексами. Более того, так как фильтр пакетный, то правила индексирования в нём написаны от значения длины пакета, которое взято из каких-то “максимально обобщённых” соображений. Эти соображения, определяющие длину, не учитывают формата ClientHello и возможного увеличения размеров этого сообщения сразу на несколько сотен байтов. В результате – ожидаемые индексы сдвигаются за допустимые границы, даже в следующий пакет, фильтр перестаёт срабатывать так, как срабатывал раньше, но начинает новые сообщения от браузера Chrome считать дефектными, сбрасывая соответствующее TCP-соединение.
Комментировать »
Описание предназначения системы доменных имён Интернета (DNS) нередко сводится к упоминанию про сопоставление “символьного имени” (имя хоста) и “цифрового адреса” (IP-адрес). Но это лишь одна из самых часто используемых функций, которые реализует DNS. Общее же, полное представление о DNS нужно составлять по другой модели: DNS – это глобальная, распределённая база данных, использующая концепцию “ключ-значение”, с иерархическим индексом имён ключей, дополнительной типизацией записей и управляемым кэшированием. В случае поиска IP-адресов для веб-узлов в качестве ключа используется имя узла (хостнейм, доменное имя), а в качестве искомого значения – IP-адрес (или несколько адресов), при этом используется тип записи – A-запись.
То есть, для определения IP-адреса test.ru в глобальной DNS производится поиск “документа” по ключу “test.ru” с извлечением из этого “документа” A-записи, в которой содержится IPv4-адрес. A-записи – это малая часть. В DNS хранятся данные многих типов, например: AAAA – адреса IPv6, MX – имена почтовых серверов, SSHFP – отпечатки хост-ключей SSH и др. При этом, хоть A-записи и очень важны для работы самой DNS, они не являются основными. Основные записи, в смысле иерархии, это SOA-записи (определение основных параметров доменной зоны) и NS-записи (определение списка серверов имён).
DNS позволяет выполнять обратное преобразование – IP-адрес в символьное имя. Но для этого всё равно используется схема “ключ-значение”, где в качестве ключа выступает DNS-имя так называемой обратной зоны, которое формируется из октетов (байтовых элементов) IP-адреса. Это имя располагается в технической зоне .ARPA. То есть, никакого “обратного” поиска “ключа” по “значению” – в DNS нет, но есть прямой поиск записей в специально сконструированных обратных зонах по значению имени, взятому в качестве ключа. Пример обратной зоны: 1.1.1.1.in-addr.arpa – соответствует IPv4-адресу 1.1.1.1 (сервис Cloudflare one.one.one.one).
Если обратную зону в DNS не внести, то и определить через DNS соответствие IP-адреса символьному имени только по IP-адресу и штатным способом – не выйдет. (Но, конечно, можно просканировать все доступные доменные зоны по всем доступным ключам (именам) на предмет A-записей и, таким образом, найти имена, соответствующие данному IP в прямой записи; этих имён может быть очень много.)
Поиск записей в DNS производят программы-резолверы, которые опрашивают DNS-серверы в соответствии с иерархией ключей (DNS-имён): так, tls.dxdt.ru – это имя третьего уровня, находящееся внутри dxdt.ru, а dxdt.ru – второго уровня внутри .ru, а ru – первого уровня внутри корневого домена, имя которого состоит из пустой строки и, при использовании полной записи, тоже отделяется точкой справа, вот так: tls.dxdt.ru. – здесь корневой домен идёт после крайней правой точки. Совокупность программ и протоколов, используемых для поиска в DNS, тоже нередко обозначается буквами D, N и S, но здесь S – это сервис (service), то есть, речь уже идёт про сервис доменных имён.
Основой работы DNS как сервиса является кэширование данных на разных уровнях, в основном, кэширование обеспечивают программы-резолверы. Кэширование решает две основных задачи: это исключение излишней нагрузки и сохранение доступности при кратковременных отказах. Для обеспечения работы сервиса, записям, публикуемым в DNS, сопоставляются различные технические параметры, самый важный из них – это TTL (Time To Live), значение которого позволяет определять динамические параметры кэширования.
При штатной работе, DNS действует именно как база данных: из неё извлекаются далеко не только IP-адреса узлов, про которые так часто пишут, но и списки имён серверов, значения ключей и подписей DNSSEC, значения TXT-записей. Так как DNS является в Интернете всеобъемлющей системой, то и DNS-записи, отличные от A- и AAAA-записей, постоянно используются. Так, TXT-записи, позволяющие опубликовать под заданным именем текстовую строку, повсеместно используются для подтверждения тех или иных прав по управлению доменной зоной, например, при выпуске TLS-сертификатов или при публикации “почтовых” ключей DKIM.
Комментировать »
Stack Overflow некоторое время назад запретил использование LLM (ChatGPT и пр.) для генерирования и ответов, и вопросов на сайте. Причины запрета были названы разные, но ситуация стала особенно забавной на днях, когда из OpenAI объявили, что контент Stack Overflow будет официально предоставлен для “обучения” ChatGPT (пока что – несмотря ни на какие протесты некоторых пользователей). То есть, если бы изначального запрета на использование LLM не было, то могла бы возникнуть ситуация, когда в ChatGPT транслируется выдача ChatGPT, что далеко не всегда хорошо (хоть и составляет существенную часть штатной работы данных LLM).
Комментировать »
Что касается новостей про атаку TunnelVision, которой соответствует CVE-2024-3661, и про которую сейчас СМИ пишут, что это “уязвимость всех VPN”. Очень (слишком даже) подробное изложение есть по исходной ссылке, однако там начинается весьма издалека, с самых азов. Но для сетевого инженера саму атаку можно детально описать в несколько строчек: к VPN это отношения не имеет, а речь идёт про добавление маршрутов на клиентское устройство средствами DHCP-сервера, маршруты, соответственно, добавляются с привязкой к сетевому интерфейсу на уровне ОС клиента и ведут на перехватывающий узел в той же локальной сети. Дальше работает more-specific, потому что для интерфейса VPN прописано, предположим, 0.0.0.0/0. Понятно, что таким способом можно перенаправить произвольный IP-трафик на промежуточный узел до того, как этот трафик уехал на клиенте в туннельный интерфейс, поднятый приложением VPN. Трафик поэтому будет в открытом виде. Это, собственно, всё.
DHCP-команда, которая позволяет прописать маршруты в интерфейс клиенту – известна, это никакая не уязвимость, а штатная функция DHCP. Работает, конечно, если устройство не только обрабатывает данную команду, но и реально маршруты устанавливает (Android – игнорирует, поэтому атака не работает для Android). Если локально маршруты от DHCP фильтровать или игнорировать, то тоже атака не сработает (интересно, что это очередной раз показывает, насколько правильным является использование виртуализации: если доступ через виртуальную машину, то, скорее всего, навязанные маршруты через виртуальный интерфейс сами не пройдут; то же самое относится и к сетевой “виртуализации” вообще – если подключаться со своим локальным сегментом, например, через свою точку доступа, то атака опять не сработает).
Собственно, авторы исходного сообщения прямо пишут, что вопрос, является ли TunnelVision уязвимостью – спорный, а дальше объясняют, что публикация направлена на противодействие массовым маркетинговым уловкам провайдеров VPN-сервисов, когда заявляется, что какой-то VPN-клиент защищает трафик при подключении к “недоверенной сети”.
Комментировать »
Снова пишут про то, что в TLS браузера Chrome длинное ClientHello с ключом Kyber768 ломает обработчики TLS-трафика на каких-то “специальных” веб-серверах и на промежуточных фильтрах. Между тем, чтобы разобраться, как там и что происходит, достаточно посмотреть на конкретное ClientHello, но в некоторых деталях. В качестве примера я взял сообщение от браузера Chrome 124 в том виде, как оно отображается на тестовом сервере TLS. Чтобы просмотр дампа не был скучным, листинг перебивается техническими пояснениями.
Итак, ClientHello TLS 1.3 с постквантовой криптосистемой Kyber768 внутри. CH здесь уже извлечено из TLS-записей и разобранно на элементы: то есть, здесь не учитываются и не упоминаются дополнительные байты, которые расходуются внутри структуры CH на представление полей – идентификаторы, длина записи; обычно – это несколько дополнительных байтов на один элемент структуры. Если бы разбирать и эти байты, то описание излишне усложнилось бы (подробности – можно прочитать в техническом описании TLS).
Version: 0x0303 Cipher suites: 0xBABA,0x1301,0x1302,0x1303,0xC02B,0xC02F,0xC02C,0xC030 0xCCA9,0xCCA8,0xC013,0xC014,0x009C,0x009D,0x002F,0x0035
Начальная часть сообщения ClientHello (далее – CH) содержит “исторический” номер версии (здесь указано 0x0303) и перечень шифронаборов. Полезных данных: два байта – номер версии, 32 байта (16*2) – идентификаторы шифронаборов.
Client Random: 85:32:22:08:24:07:B2:98:F3:23:08:4D:A5:FB:E4:59:41:93:13:88:AA:58:53:4E:B4:EF:E7:DA:E8:78:FE:71 Client SessionID: C0:39:BC:CE:BB:60:5F:76:D8:75:F9:84:69:E9:9F:C2:AE:7B:8F:D5:9C:E8:01:51:71:9D:21:D2:13:26:DB:5A
Случайное значение от клиента (Client Random). А также клиентский “идентификатор сессии” – в TLS 1.3 этот идентификатор играет роль простого сигнала и ни на какую сессию не указывает.
Здесь всего 64 байта данных, по 32 на каждое поле.
Далее идёт важная часть, которая, собственно, определяет значимые параметры TLS-соединения – набор расширений CH.
Extensions: Type: 14906 (0x3A3A); "_undef_ (GREASE)" Type: 35 (0x0023); /non-TLS-1.3/ Type: 23 (0x0017); /non-TLS-1.3/ Type: 16 (0x0010); "application_layer_protocol_negotiation" 00:0C:02:68:32:08:68:74:74:70:2F:31:2E:31 Type: 65281 (0xFF01); /non-TLS-1.3/ 00
Здесь 0x3A3A (тип 14906, первое расширение) – это пример того, что называется GREASE, а именно – специальных, заведомо неподдерживаемых, значений и идентификаторов, которые Chrome дописывает в TLS-сообщения с целью (как заявлено) проверки корректной работы парсеров и прочего программного обеспечения, задействованного в обработке TLS. Такие обработчики, согласно спецификации, должны успешно игнорировать неизвестные расширения и параметры (если контекст позволяет, конечно). Так что, вообще говоря, добавление разных там новых “постквантовых ключей” не является чем-то особенным – всякие фиктивные элементы писались в браузерные сообщения и раньше, именно для того, чтобы обновления не оказывались полной неожиданностью (ниже нам встретятся и другие GREASE). Другие расширения из этого фрагмента, с типами 35 (session_ticket), 23 (extended_master_secret), 16 (ALPN) и 65281 можно не рассматривать: они небольшие по объёму (например, extended_master_secret – это всего лишь сигнал, вообще не содержащий байтов данных), часть из них не поддерживается в TLS 1.3. Поэтому – переходим дальше.
Как говорится, а вот и он – постквантовый элемент. Клиентский открытый ключ Kyber768 содержится уже в следующем расширении – key_share. Оцените огромный размер данных, которые тут приводятся без сокращений.
Type: 51 (0x0033); "key_share" _undef_ (GREASE) (0xAAAA) Unsupported group: 0xAAAA (_undef_ (GREASE)) X25519Kyber768Draft00 (0x6399) Hybrid: X25519 + Kyber Len (octets, dec.): 1216 Key share data: X25519 x = 0xF2C744A07B3BC36F6C427620351A009D29BB36E6EF259A177A3881ECEB22100D Kyber768 client public key: Vpoly_1 (packed): 6CA39FB332275395989A56958E6B61A7B3B447D6A2C9062837E39695B44E4A5B 36C9A7B06F4A912ED6ABC2E3BD2FD8584BE42F5822A3A54A4CC14812F3D87A05 5371F2E1222817A63FAA531CD7691DE59694F9B4ACD3B8CD638A44B9B566C094 3A95B7DCB186CC840C53A90041FB15FFBB214E3BCE8AB0C3D278897A61992601 BB88427608A8AEC6385C0C6319A56B8B47CA240F3A134DD6AF4B56A6333158A9 D391B495A76EA0C5F67C49457042AFFB508766414C88A8EA23B1328723FC9199 8BA78414527F2DC234C0213CF5DAB976910EA3DC641C8B818FF73F4CEB53C929 C03F61CFD8A04CE88A3EB16CCAE02C9541438A16D4A7FE8129F7F04C0C0A9E14 60ACA4049F84C2C4E5DB1B4185CF0FE8C305333CBC7B3970A27E42C23F47F003 E3815FDE20830B912501E388BEB9B14399ADD2EA174E3C040810917E555084E1 5B75B9599914523799B6885721D08A46741501EBACA747C905B7AA31E3D3137C 718B50A908DC111E49161448B102D3F0411EA70D9F91CFF6F50D5D54B9AB7B11 Vpoly_2 (packed): 1356BAA03CAD6E2730C334C24D492E6A11088F7B036A7ACBEF26407C1A9DCDFA 473D677C3447915AE28EB094326093668FC27DCB85086219A1A0E6A6FC367CE0 9A4396EA75FAFA1CD336311DE505BE5075A36C436B58673CF6387AF45BDBD523 C082864EB6BD20E6A587C99976FA04C9548FB9731BC5B80D483984D8E84D89A3 8A0D210D58C22C9DA0316D9214B45B46C7353228C67A62F101DD79267C071CEE 9C1FA2DA976294AD6031C245397BDFB11A3AF012DF154B6D126439F579F85C38 77AB844586159ECCAD0D468A3D94A5DABA43B26722B4C24FEFDC19FC62355341 29B1FBABC7D242DDEB59DB00C564546DBD384653CCB55436BCCA4B7C4BA585E3 50B078A48B8F02C9BA79154DF463E42538DB7616AC04C9C1284F0E2918009CAE 49EB18708A2BD322A3A613CCCF43B3CA288780546FEBF03B6FC3394816359406 5642DC4930B4B36D5B5122A90871006975496515650608E632414B5054019BB5 CB280DF34DA9087AB2FA2ADB94588AB2A8C8D3CA3DAB7248357001D0C175269C Vpoly_3 (packed): AAF30D9EA1ADEF802799581653A0A0D4D692EB2B644F6C84059388947838138A 1D24464054A9A3E9385FD3E4A6C0C56D09D80F984705B2E4B4244A4D67C3CD58 7739688170695AC9AA4C354A349AB04ACBD4753E6B519468EB900A290C3AD255 A004307B1572C0072946B73639F897D434086C515F6BBA53BB10B6A3D4B4AC86 58E4A4C3EE452C3D7442536756D4F7041775897C2240C4B437CC97CC5E4270FD 986DEE9842831B1F233B543F724A9E5B0446BB22CF6C8AC278CD4E275482F61B A3461582291443967ED0AA78723A2EBE448AC24726D8EA8F5264BC45A4A7D8B4 C04EFC7A7271AA361B454EE43365644E5DA9A5F8A5A838D4C93EB6970716B98D 5617F4E4829E93A816432C9B7621ECF2CB5A75BDD4446F58BC57F1A36215467F 1722A31FFA2432574F028848A92A0FC5C48C4F391FDF2214429454A6015DD9E6 496A3B1D5F9768C5326AB2997E038CA5E7E34347D5C5C8E7AE00A9CB48FA4A43 54768F3C586430B8C4E8C3CAE13EE0265910A0B01FA037CAE333B13B63601397 Rho (bytes): 44D2E20D0D57AA501ED3DE916106FF5DA95E4BE2AD4335034F2C757352305980 X25519 (0x001D) x = 0xFB6C61B9A2E5323674FD2C49FA02DF5E1335F52EFBF984C9FC2401F01B1F7C5E
В TLS 1.3 стороны уже на самом первом этапе вычисляют общие секретные ключи, чтобы перейти на защищённый обмен данными. Для этого свою часть открытых ключей (или открытых значений протокола Диффи-Хеллмана, что здесь эквивалентно) должен прислать клиент. Клиент присылает эти ключи в расширении key_share.
В данном случае браузер Chrome прислал нам значение X25519 (внизу) и гибридный набор из X25519 и Kyber768 – то есть, X25519Kyber768draft0 (идентификатор 0x6399 – в начале). Важно не запутаться: криптосистема с постквантовой стойкостью тут одна, она называется Kyber768 (“на научном языке” это KEM – Key Encapsulation Mechanism). Однако в TLS эта криптосистема внедряется в гибридном варианте, то есть, на прицепе к классической, хорошо отработанной, криптосистеме X25519, которая есть разновидность реализации протокола Диффи-Хеллмана. Данный гибрид всё ещё считается “черновым вариантом” – draft. Поэтому полное название X25519Kyber768draft0.
Если приглядеться, то в этом же расширении есть ещё один, не столь массивный, блок, названный X25519. Это другое, отдельное открытое значение X25519, которое может быть использовано сервером, если сервер не поддерживает X25519Kyber768draft0. К входящему в гибридный вариант значению X25519 свободный вариант отношения не имеет. Это та же криптосистема X25519, в гибриде она работает абсолютно и точно так же, как и без “гибридизации”, но название отличается, как отличаются и значения ключей (обозначены “x”).
Постквантовая часть ключей указана в блоке “Kyber768 client public key”. Ключ Kyber768 состоит из четырёх обособленных значений: это три полинома (Vpoly_N) и параметр Rho. И только лишь ключ Kyber768 занимает уже 1216 байтов. X25519 добавляет лишь 32 байта (в составе гибрида).
Другие элементы расширения key_share, которые тоже отмечены GREASE, это, опять, фиктивные значения, как и в следующем расширении – supported_groups.
Type: 10 (0x000A); "supported_groups" 0xAAAA (_undef_ (GREASE)) 0x6399 (X25519Kyber768Draft00) 0x001D (X25519) 0x0017 (Secp256r1) 0x0018 (Secp384r1)
В этом расширении – поддерживаемые клиентом схемы криптосистем. Расширение называется “Поддерживаемые группы” (supported_groups). “Группы” здесь – это технический термин, обозначающий математическую структуру (группу), которая применяется в той или иной криптосистеме (кстати, можно сказать, что “схема”, с математической точки зрения, даже более технический термин, который вполне можно так применить, но, конечно, это лишь случайное совпадение).
Данное расширение всего лишь перечисляет идентификаторы параметров, которые клиент готов использовать. Часть ключей – уже передана в составе key_share. Поэтому тут и присутствуют X25519Kyber768Draft00 и X25519. Однако сервер может не поддерживать ни X25519Kyber768Draft00, ни X25519. В таком случае предстоит выбрать что-то из оставшихся вариантов: Secp256r1 и Secp384r1, под которыми подразумевается протокол Диффи-Хеллмана (DH) на кривых P-256 и P-384. А GREASE – выбрать нельзя. Для перехода к другой криптосистеме сервер, в ответ на CH, отправляет сигнальное сообщение HRR (HelloRetryRequest), указывая в расширениях к нему предпочитаемую криптосистему. Пересогласование криптосистемы для DH поддерживается на тестовом сервере tls13.1d.pw – так что эффект нетрудно увидеть, понажимав Ctrl+F5 (Refresh) в браузере: при пересогласовании клиент пришлёт новое CH, уже с другим составом key_share.
Возникает резонный вопрос: поддержка Kyber768 на серверной стороне не очень-то распространена, нужно ли пересогласование при каждом CH от Chrome с Kyber768? Нет, в типовом случае, серверу не нужно ничего пересогласовывать – сервер может проигнорировать гибридный постквантовый набор и сразу использовать X25519 (поддержка есть практически повсеместно), потому что ключ этой криптосистемы указан в CH от Chrome (не гибридный, а отдельный). Если, конечно, сервер не поддерживает X25519, тогда пересогласовать криптосистему потребуется, но не из-за наличия Kyber768.
Следующее расширение – это фиктивное ECH (Encrypted Client Hello).
Type: 65037 (0xFE0D); "ECH /DRAFT/" Type: 0x00 (Outer) HKDF: 0x0001 (HKDF-SHA256) AEAD: 0x0001 (AES-128-GCM) Config id: 0x04 Encapsulated key (bytes): 08FC1E6C6A441874D38689375F9C906827516F2F306BBD8B2376569F99CF0069 Payload (dummy): ECADC2C291D6311FCD925306392EE88CD057D42178C0B60EF5B14814F2CF669E 05230A0F3D6AABADA0A3EB78D240E22BE2DE5893A50B3AEC4056B77B5CACF7C9 07F5E6EE853268C23595E22F59E9D190BE9ECCD05B76092CBA00FCCE1C072283 7CBE371C871817540D8E9429CB10F4CCA3089AB36154D7AE2578FF5D12884F3D 437AB7A97E0FDA19DCC4B423A4DFD2CF
ECH служит для доступа к скрытым сервисам. Базовое применение: сокрытие имени узла, с которым устанавливается TLS-соединение. Chrome включает фиктивное расширение в CH даже для узлов, которые ECH не объявляли. Это метод придания единообразия TLS-трафику. Расширение ECH устроено довольно сложно, содержит внутри дополнительную структуру и большое по объёму данных поле Payload, которое, в случае фиктивного расширения, имитирует полезные данные ECH (зашифрованное CH). ECH, в данном случае, добавляет ещё 182 байта.
Type: 00 (0x0000); "server_name" 00:00:0E:00:00:0B:74:6C:73:31:33:2E:31:64:2E:70:77 hostname: tls13.1d.pw
Расширение SNI, содержащее имя узла, с которым устанавливается TLS-соединение. Именно данные этого расширения и должно скрывать ECH (в данном случае – ECH не поддерживается). Обычно, это расширение не очень большое по объёму (но зависит от используемого имени).
Type: 45 (0x002D); "psk_key_exchange_modes" 01:01 Type: 17513 (0x4469); /non-TLS-1.3/ 00:03:02:68:32 Type: 43 (0x002B); "supported_versions" 0x8A8A (_undef_ (GREASE)) 0x0304 (TLS 1.3) 0x0303 (TLS 1.2) Type: 05 (0x0005); "status_request" 01:00:00:00:00 Type: 13 (0x000D); "signature_algorithms" 00:10:04:03:08:04:04:01:05:03:08:05:05:01:08:06 06:01 Type: 11 (0x000B); /non-TLS-1.3/ 01:00 Type: 27 (0x001B); /non-TLS-1.3/ 02:00:02 Type: 18 (0x0012); "signed_certificate_timestamp" Type: 10794 (0x2A2A); "_undef_ (GREASE)" 00
Из оставшихся расширений в контексте этой записки интерес представляет только supported_versions (тип 43): в TLS 1.3 именно это расширение содержит настоящий список поддерживаемых клиентом версий TLS. Chrome, помимо очередного GREASE, передаёт здесь идентификаторы версий 1.3 и 1.2. Наличие supported_versions и делает это CH сообщением версии TLS 1.3.
А заканчивается набор расширений всё тем же GREASE.
Итак, на примере конкретного ClientHello хорошо видно, что ключ Kyber768, действительно, занимает основную часть сообщения. Обычный вариант CH, без “постквантовой стойкости”, будет отличаться только отсутствием ключа X25519Kyber768Draft00, всё остальные поля – применяются точно так же.
Комментировать »
Пишут, что поддержка постквантовой криптосистемы X25519Kyber768 в Chrome свежей версии ломает TLS в каких-то серверных реализациях или на промежуточных узлах-фильтрах, а происходит это из-за того, что начальное сообщение ClientHello получается слишком длинным.
Вообще, X25519Kyber768 добавляет 1216 байтов, что, действительно, сравнимо с размером типичного ClientHello (без “постквантовых” данных, но с разными расширениями). Скажем, даже длинный FFDHE3072 (“мультипликативный” вариант Диффи-Хеллмана в TLS 1.3) использует только 384 байта. Chrome, надо сказать, FFDHE3072 не поддерживает, но зато дописывает фиктивное ECH-расширение (это не связано с постквантовой криптосистемой).
То есть, вовсе не трудно поверить, что в каких-то, – не самых качественных, – реализациях TLS, “постквантовое” ClientHello может читаться лишь частично, потому что оно не влезло в один ответ функции чтения TCP-сокета. Такое нередко приключается в системах инспекции трафика, разных “корпоративных” сетевых экранах (как бы, stateful), да и в прочих инструментах. С другой стороны, пытаться читать TLS-сообщения только по данным TCP-пакетов, игнорируя заголовки самих TLS-записей, в которых указана полная длина, – не самый лучший способ реализации TLS. Особенно, если речь про некоторый “продвинутый” механизм “обеспечения безопасности”, типа брандмауэра.
Комментировать »
Где именно в криптосистеме электронной подписи ECDSA “работает” эллиптическая кривая?
Посмотрим, для начала, на значение подписи, которое состоит из двух параметров – (R, S). Здесь R – это координата X точки на используемой эллиптической кривой, а именно, X-координата точки k∘G, где G – точка кривой, называемая генератором (зафиксированный параметр криптосистемы), а k – секретное уникальное значение (ECDSA nonce). Запись k∘G, – “умножение на скаляр”, – означает повторное сложение точек: G⊕G⊕G⊕…⊕G, где G встречается k раз, а “⊕” – обозначает операцию в группе точек кривой, то есть, сложение точек. (Умножение тут лучше было бы записать [k]G, например, но это детали.)
На значение k накладываются различные ограничения, но это всего лишь натуральное число (конечно, так можно сказать про всё, что встречается “в компьютерах”). Структура кривой такова, что есть пары точек с совпадающими X-координатами, но различными Y-координатами. Этот момент нередко используется в атаках на реализации ECDSA. В данном случае – R это именно X-координата.
Эллиптическая кривая непосредственно использована для вычисления одного параметра подписи – R, который, впрочем, сразу “превращается” из точки, как кортежа значений, задаваемых дополнительной структурой уравнения кривой, в единственное число.
Нетрудно заметить, что здесь, в процессе вычисления R, не использовано никаких значений, связанных с подписываемым сообщением или с секретным ключом – эти элементы пока что даже не упоминались. Параметр R служит в качестве опорного значения, необходимого для проверки подписи – к R должно сойтись значение после “невидимых сокращений”, заложенных в уравнение проверки подписи.
Это основная математическая идея ECDSA: базовое уравнение так устроено, что части структуры преобразования, вынесенные наружу в составе публичных значений, сокращаются, если ключ проверки соответствует подписи (и параметрам), но не сокращаются в почих случаях.
Сокращающиеся структуры не видны, а вычислить их, – то есть, обратить, – по открытым значениям и параметрам, сложно. Концептуально это напоминает, например, RSA, где внутри открытого ключа всегда содержится структура, связанная с разложением на простые множители, благодаря которой криптосистема работает. Тут необходимо обратить внимание на то, что, во многих практических реализациях, значение k может вычисляться с использованием и подписываемого сообщения, и секретного ключа – например, так делается в схеме детерминированной ECDSA. Но “классическая” ECDSA такого, вообще говоря, не требует. Это, впрочем, один из самых проблемных моментов реализаций данной криптосистемы – так, если третья сторона знает параметры генератора псевдослучайных чисел, который использовался для получения k, то эта третья сторона без особых трудностей может вычислить секретный ключ по значению подписи и подписанного сообщения (см. ниже).
Итак, эллиптическая кривая, заданная для ECDSA, использовалась для вычисления R. Где ещё встречаются операции с точками? Прежде всего – вычисление открытого ключа. Открытый ключ в ECDSA это точка на кривой, а получается он из секретного значения d путём умножения генератора: Q == d∘G. То есть, d – целое число. Принцип эквивалентен вычислению r. Однако, в отличие от r, открытый ключ Q повсеместно записывают как пару координат (X,Y), но это только способ записи, потому что достаточно сохранять X и один “бит знака” для Y.
Вторая часть подписи ECDSA – параметр s. И значение этого параметра вычисляется уже без использования операций с точками кривой. Уравнение для s следующее:
S == k^(-1)*(H + Rd)
– здесь, кроме уже определённых k, R и d (d – секретный ключ), используется значение H – это и есть подписываемое сообщение (технически, это значение хеш-функции от сообщения).
Все значения в данной формуле – это натуральные числа (даже k^(-1)), а не точки. Поэтому тут использованы другие значки для обозначения операций: “+”, “*”, “^(-1)” – это “обычные” операции сложения, умножения и взятия обратного по умножению. “Обычные” в кавычках по той причине, что вычисления проводятся по модулю некоторого числа. То есть, это привычная арифметика остатков. Положительное число, по модулю которого проводятся операции, это так называемый порядок группы точек кривой. Можно считать, что порядок – это количество доступных для вычислений точек кривой. Порядок обозначают, например, P, а тот факт, что это арифметика остатков “по P” записывают как (mod P). Так что свойства кривой тут участвуют только косвенно. Взятие обратного по умножению – k^(-1) – это нахождение такого числа, которое даст 1 (mod P) при умножении на k. Так как вычисления выполняются (mod q), то k^(-1) тоже будет целым числом. Пример: 4*2 == 1 (mod 7) – так как 8/7 – даст остаток 1. Обратите внимание, что все вычисления дальше – тоже (mod P), но отдельно этот момент упоминаться не будет, так как, для практических целей ECDSA и для простого P, свойства вычислений совпадают с привычными операциями в рациональных числах (кроме сложения точек кривой).
Раз это обычная арифметика, то и по формуле для S нетрудно увидеть, что если известны k, H, R, S, то легко вычислить секретный ключ d – просто перепишем уравнение относительно неизвестной переменной d. Значения H, R, S – публично доступны: первое из них это подписанное сообщение, а два других – сама подпись. Никаких “хитростей” эллиптической кривой тут уже не задействовано, поэтому и никакие особенности арифметики эллиптических кривых конкретно на этом направлении криптосистему не защищают. (Более того, если известно не точное значение, но какие-то дополнительные свойства k, то уравнение S можно превратить в неравенство, составить набор “приближений”, который позволит найти приближённое значение для секретного ключа, чтобы потом быстро подобрать его точно по значению открытого. Но это тема для другой записки.) Итак, при вычислении S операции на эллиптической кривой не используются.
Проверка подписи в ECDSA использует следующее уравнение:
C == (H*S^(-1))∘G ⊕ (R*S^(-1))∘Q
– обратите внимание, что тут разные обозначения операций, чтобы можно было различить операции с точками и операции с числами; а значение Q, – открытый ключ, – это d∘G. Работает вся эта схема потому, что, из-за свойств сложения в группе точек кривой, можно операцию сложения точек ⊕ спустить в натуральные числа, вот как: 3∘G ⊕ 5∘G == (G⊕G⊕G)⊕(G⊕G⊕G⊕G⊕G) == 8∘G. При этом, если подставить вместо S формулу вычисления S (см. выше), то в правой части сократится всё, кроме k. Получим, что C == k∘G, а X-координата C должна совпасть с R, если, конечно, подпись верна и вычисления верны. И здесь эллиптическая кривая используется непосредственно для вычисления итогового значения, а именно – умножение на скаляры точек G (генератор) и Q (открытый ключ), сложение получившихся точек.
Комментировать »
Кстати, серверы Google (например) уже поддерживают X25519Kyber768 – см. скриншот ниже, – а это означает, что можно найти новые уязвимости, связанные с поддержкой этой криптосистемы.
Комментировать »
В Chrome версии 124 всё же включили по умолчанию гибридную криптосистему с постквантовой стойкостью X25519Kyber768 для TLS. Проверить можно на тестовом TLS 1.3 сервере: tls13.1d.pw – там поддержка есть с сентября прошлого года.
(Поскольку “Яндекс.Браузер” является клоном Chrome/Chromium, то поддержка X25519Kyber768 по умолчанию должна появиться и там.)
Комментировать »
Сообщают, что “Яндекс”, вместо поиска сайтов с выдачей ссылок на найденное, переходит к использованию синонимайзера, который будет пользователю тут же, в приложении от “Яндекса”, показывать переписанный текст, “найденный в Интернете”, – то есть, скопированный с тех же сайтов, – но уже без того, чтобы пользователь куда-то там переходил, на какие-то сайты-источники текстов для “Яндекса”. Решение называется “Нейро” и относится к модному классу ИИ LLM. Да, формально, там всё ещё упоминается “отдельный блок ссылок” на источники, но “задача пользователя” уже формируется как получение ответа в виде развернутого текста тут же.
Занятно, что в описании данного сервиса утверждается следующее: “Пользователь может задать ему любой вопрос. Чтобы ответить на него, нейросети изучат и подберут необходимые источники в результатах поисковой выдачи”. Обратите внимание: “нейросети изучат и подберут”. То есть, тут, буквально и прямолинейно, развивается основная проблема, связанная с непониманием современных LLM/ИИ-сервисов пользователями: пользователи ошибочно полагают, что нейросети “изучают” (“анализируют”) источники и потом готовят ответ. Однако “многослойные синонимайзеры” ИИ ничего не исследуют в принципе, поскольку лишь строят цепочки слов.
Комментарии (1) »