Пишут, что поддержка постквантовой криптосистемы 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∘G. Получим, что C == k∘G, а X-координата C должна совпасть с R, если, конечно, подпись верна и вычисления верны. И здесь эллиптическая кривая используется непосредственно для вычисления итогового значения, а именно – умножение на скаляры точек G (генератор) и Q (открытый ключ), сложение получившихся точек.



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

Кстати, серверы Google (например) уже поддерживают X25519Kyber768 – см. скриншот ниже, – а это означает, что можно найти новые уязвимости, связанные с поддержкой этой криптосистемы.

Google Chrome Screen



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

В Chrome версии 124 всё же включили по умолчанию гибридную криптосистему с постквантовой стойкостью X25519Kyber768 для TLS. Проверить можно на тестовом TLS 1.3 сервере: tls13.1d.pw – там поддержка есть с сентября прошлого года.

(Поскольку “Яндекс.Браузер” является клоном Chrome/Chromium, то поддержка X25519Kyber768 по умолчанию должна появиться и там.)



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

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

Занятно, что в описании данного сервиса утверждается следующее: “Пользователь может задать ему любой вопрос. Чтобы ответить на него, нейросети изучат и подберут необходимые источники в результатах поисковой выдачи”. Обратите внимание: “нейросети изучат и подберут”. То есть, тут, буквально и прямолинейно, развивается основная проблема, связанная с непониманием современных LLM/ИИ-сервисов пользователями: пользователи ошибочно полагают, что нейросети “изучают” (“анализируют”) источники и потом готовят ответ. Однако “многослойные синонимайзеры” ИИ ничего не исследуют в принципе, поскольку лишь строят цепочки слов.



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

Многие используют PuTTY, а также – ключи на кривой NIST P-521, потому что считают (не без оснований), что здесь бо́льшая разрядность (например, по сравнению с кривой P-256) обеспечивает бо́льшую стойкость. В PuTTY выявлен дефект реализации ECDSA на данной кривой, который приводит к раскрытию секретного ключа по набору подписей, полученных от него – то есть, большее количество разрядов не только не помогло, но и сыграло в сторону ухудшения. Это CVE-2024-31497.

Математический смысл уязвимости следующий. Алгоритм вычисления подписи в ECDSA использует nonce – это секретный, (псевдо)случайный параметр, который обычно обозначают k. Здесь в nonce, из-за ошибки в коде, зафиксировали девять битов в начале (или в конце) записи. (Девять, видимо, потому, что 521-512 == 9.) Речь тут не про секретный ключ, а про дополнительное значение: секретный ключ в обычной ECDSA не меняется от подписи к подписи, что для данной атаки имеет определяющее значение, а вот параметр/nonce, при этом, меняется. Однако, если известно дополнительное распределение для k, как в случае данного дефекта, то часто можно вычислить секретный ключ, задействовав некоторое количество значений подписей. В случае CVE-2024-31497, девять фиксированных последовательных битов позволяют раскрыть секретный ключ за, как пишут, примерно, 60 подписей.



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

На сайте журнала “Интернет изнутри” доступен свежий номер в формате PDF. Отдельно порекомендую статью «Квантовые коммуникации: “пик хайпа” или “плато продуктивности” с точки зрения дилетанта» (с. 31) и, конечно, исключительный рассказ из первых рук про историю РосНИИРОС и домена RU (с. 59).



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

Записка про процесс валидации TLS-сертификатов, сопоставления сертификата с TLS-узлом и аутентификации этого узла; всё – на примере TLS для веба (то есть, “HTTPS в браузерах”).

Валидация – это проверка и подтверждение того, что сертификат действует, соответствует сценарию использования ключа и подписан доверенным Удостоверяющим Центром (УЦ или CA в английском варианте). Аутентификация, в данном случае, состоит в проверке соответствия имён (в сертификате и в параметрах соединения) и получении подтверждения, что аутентифицируемый узел имеет доступ к секретному ключу, соответствующему открытому ключу из сертификата.

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

Для описания процесса, прежде всего, важны три типа сертификатов:

1) сертификат доверенного УЦ; обычно, это самоподписанный сертификат (см. ниже), который содержит открытый ключ корневого доверенного УЦ, список таких сертификатов входит либо в дистрибутив браузера, либо в дистрибутив операционной системы;

2) сертификат промежуточного УЦ; это как раз пункт, который традиционно является источником многих хитрых деталей; промежуточный УЦ возникает потому, что непосредственно от корневых ключей “обычные” (оконечные) сертификаты сейчас на практике не выпускают, а выпускают сертификаты промежуточных УЦ – секретные ключи, соответствующие открытым ключам из этих сертификатов, служат для подписи оконечных сертификатов, которые описаны в следующем пункте;

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

В ходе валидации выстраивается так называемая “цепочка доверия”. Цепочка выстраивается при помощи проверки подписей на сертификатах, но не только. Эта цепочка – иерархия сертификатов, в которой они соединяются по соответствию имён и открытых ключей. В сертификатах есть поля Issuer/Subject. Issuer – “Издатель”, название того УЦ, который этот сертификат выпустил. Subject – “Субъект”, название, к которому этот сертификат привязывает опубликованный в нём открытый ключ при помощи подписи от ключа Issuer (“Издателя”).

Например, для dxdt.ru цепочка может быть такой (здесь корневой сертификат – слева, ISRG Root X1, а “доверие” распространяется справа налево): ISRG Root X1 — R3 — dxdt.ru. Открытые ключи привязываются в этой цепочке к именам при помощи проверки подписей. Если проверка удалась, то ключ – верный. Ключи и имена обычно используются парой (в принципе, в списке может оказаться несколько одинаковых имён с разными ключами, хоть так быть и не должно, – в таком случае, приоритет будет у значения ключа).

Для корневого УЦ сертификат является просто контейнером ключа, этот сертификат “самоподписанный” – то есть, подпись от того же ключа, открытое представление которого указано в сертификате, совпадающие значения Issuer и Subject. На других сертификатах подпись вычисляется от ключа, соответствующего другому сертификату (на него тоже указывает имя из Issuer).

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

Все сертификаты в цепочке содержат указания на то, как можно использовать ключи, указанные в этих сертификатах. Например, сертификаты УЦ содержат флаг, который обозначает, что (секретный) ключ может использоваться для подписывания других сертификатов и, например, для подписывания списков отзыва (см. ниже). Это всё помимо отдельного флага, обозначающего, что данный сертификат – сертификат УЦ. Использование ключа должно соответствовать схеме проверки – например, валидатор не должен принимать сертификат, подписанный от ключа, (доверенный) сертификат которого не содержит флага УЦ или флагов, разрешающих подписывание.

Оконечный сертификат сопоставляется по имени с именем узла, с которым браузер пытается установить соединение. Это часть процесса аутентификации узла, использующая сертификат существенным образом. Современные спецификации таковы, что тут учитывается не имя узла из поля Subject, как можно подумать. В TLS-сертификатах есть специальное расширение SAN (Subject Alternative Name), где могут быть перечислены дополнительные имена. Именно тут должно быть указано имя сервера. Например, dxdt.ru. Иначе, согласно спецификациям валидации для современного веба, которым следуют браузеры, сертификат будет невалидным для заданного имени (даже если имя указано в Subject).

Сертификаты могут быть отозваны до достижения ими срока окончания действия. Поэтому, в теории, для каждого сертификата в цепочке валидации должен быть проверен его статус (отозван или нет). В практике веба отзыв проверяется далеко не всегда. Есть два базовых способа проверки статуса сертификата – файл со списком серийных номеров отозванных сертификатов (CRL – Certificate Revocation List) и респондер протокола OCSP (Online Certificate Status Protocol); а есть специальные способы, поддерживаемые современными браузерами, например, Chrome/Chromium, и серверами. Специальные способы возникли потому, что всякое обращение к сервисам проверки статусов сертификатов раскрывает некоторую информацию о сессии браузера в сторону УЦ. Вести сервисы статуса непосредственно могут только либо сами УЦ, либо организации, которым УЦ прямо поручили реализацию такой функции, это связано с необходимым доверием, чтобы сертификаты не могли “отзывать” произвольные участники системы. Поэтому, при типовых схемах, УЦ будет узнавать о проверках статуса и видеть имена, к которым были обращения. Но можно предложить способы различного “проксирования” статусов сертификатов: сюда относятся “концентраторы” списков отзывов – пример: OneCRL, – записи “слепков” ответов OCSP – OCSP stapling, – и включение статичных списков отзыва в состав обновлений браузера (это, прежде всего, Chrome, но для важных сертификатов используют и другие браузеры, например, Firefox).

О том, где можно проверить статус сертификата, валидатор может узнаёт из состава сертификата. Адреса узлов, публикующих CRL (списки отзыва), адреса OCSP-респондеров – прямо указаны в специальных расширениях.

С отзывом сертификатов связаны два практических вывода: 1) отзыв сертификатов и корректное “оборачивание” его в необходимые сервисы – одна из больших проблем для всякого УЦ; 2) в современном вебе отзыв сертификатов сайтов, фактически, не работает (но эту неработоспособность уже несколько лет активно пытаются компенсировать внедрением сертификатов с коротким сроком действия).

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

Ссылка по теме: техническое описание TLS (где про сертификаты не так много, поскольку их техническое значение в TLS не очень велико, так как основное их значение – административное).



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

В свежих версиях веб-сервера Nginx есть полезная (и довольно экзотическая) опция для настройки TLS: ssl_reject_handshake (on | off), о которой, оказывается, мало кто знает. Опция позволяет управлять прерыванием процесса установления TLS-соединения (“хендшейка”) на стороне сервера. С помощью “ssl_reject_handshake on;” можно отклонить TLS-соединение, если в клиентском ClientHello указано имя хоста (поле SNI), которого нет на стороне сервера.

Почему это удобно. Штатная работа веб-сервера по HTTPS подразумевает, что при установлении TLS-соединения клиент передаёт имя хоста, соответствующее DNS-имени веб-узла; например, для https://test.ru/ это будет test.ru. Однако никто не запрещает клиенту обратиться с другим именем хоста в SNI. Более того, на тот же самый IP-адрес, который соответствует веб-узлу под именем test.ru, может быть направлено другое DNS-имя (другой домен). Веб-браузеры, обращающиеся по такому имени, будут указывать его в SNI, а сервер, при прочих равных, не сможет найти не только соответствующий “виртуальный хост” в конфигурации, но и подобрать корректный TLS-сертификат. Однако какой-то TLS-сертификат для установления TLS-соединения серверу нужен и, без дополнительных мер, это приводит к тому, что сервер отвечает с “первым попавшимся” (буквально) серверным TLS-сертификатом из сконфигурированных.

Если на сервере всего один виртуальный хост/веб-узел (или настроены отдельные IP-адреса для отдельных веб-узлов), то ничего нового клиент не узнаёт. Однако если виртуальных хостов много, то ответ с произвольным сертификатом приводит к нежелательным утечкам имён: клиент получит сертификат, в котором будет указано имя другого сервиса, доступного на этом же узле (или несколько имён). Администраторы и даже DevOps об этом постоянно забывают.

Сделать тут что-то корректное на уровне HTTP невозможно в принципе, так как TLS-соединение устанавливается раньше, а для каждого HTTP-ответа (403 и пр.) потребуется подходящий по имени доверенный сертификат. Да, возможны различные “костыли”, вроде использования заведомо несовпадающего сертификата-заглушки, но все они подразумевают некорректный ответ.

Указание “ssl_reject_handshake on;” для default_server (для имени хоста по умолчанию) позволяет побороть только что описанную проблему: Nginx будет прерывать именно TLS-соединение, если клиент обращается с неверным именем хоста в SNI – это, что называется, технически строгий способ. Браузер, в таком случае, выведет сообщение о недоступности узла, а не предупреждение о несовпадении имён, которое пользователи привыкли преодолевать при помощи кнопки “Всё равно продолжить”.



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

В свежих версиях браузера Chrome на сторону серверов Google предлагается передавать информацию о запрашиваемых URL в реальном времени – это такое “улучшение для безопасности”, развитие давно работающей технологии Safe Browsing, но с некоторыми занимательными особенностями.

Так, для сохранения “приватности”, во-первых, сведения передаются в виде части значения хеш-функции, полученной от URL (с некоторыми преобразованиями); во-вторых, передавать запросы планируется через прокси-серверы, которые будут удалять информацию об IP-адресах; в-третьих, сервер будет возвращать набор полных значений, совпавших по короткому префиксу запроса, а точное совпадение уже будет определять браузер локально. То есть, схема передачи данных напоминает onion-маршрутизацию: содержательная часть зашифровывается при помощи открытого ключа сервера, поэтому промежуточный узел-прокси полезных данных не видит; а сервер – не видит IP-адреса источника запроса, потому что его удалил прокси. В теории. Так как конкретному URL соответствует только часть значения хеш-функции, короткий префикс, то ответов, потенциально, может поступить много разных (это все значения, для которых совпал начальный префикс, предположим, 32 бита). Такой расклад дополнительно маскирует исходный URL из браузера. В описании есть даже картинка – см. ниже, – однако ничего не сказано о том, какой ключ используется для зашифрования данных ответа.

Google Safe Browsing and Proxy
(Image: Google.)

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

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



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

В конце 2022 года я добавил в DNS для dxdt.ru HTTPS-запись, которая тогда была описана в черновике RFC. В ноябре 2023 года черновик стал RFC 9460, где определяется способ публикации в DNS дополнительной информации о параметрах подключения к сервисам, связанным с данным именем. Например, это могут быть параметры для TLS/HTTPS, в том числе, ключи (см. ECH). Особенность использования DNS тут в том, что параметры можно получить до подключения, это, в свою очередь, позволяет устанавливать скрытые подключения.



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