Ресурсы: техническое описание TLS, LaTeX - в картинки (img), криптографическая библиотека Arduino, шифр "Кузнечик" на ассемблере AMD64/AVX и ARM64
Вот уже два с половиной месяца на dxdt.blog используются короткоживущие TLS-сертификаты от Let’s Encrypt – серверный сертификат валиден 160 часов, новый сертификат, при штатной работе, выпускается каждые двое суток, а старый – отзывается со статусом Superseded. Поделюсь некоторым опытом.
Для короткоживущих сертификатов мониторинг необходим даже больше, чем для “обычных”. Потому что отслеживать нужно событие замены сертификата через каждые два дня: если сертификат не заменился, то “что-то пошло не так” и нужно срочно смотреть, что именно, ведь срок действия сертификата совсем небольшой. Многие типовые решения для мониторинга не приспособлены для короткоживущих сертификатов.
Серверные TLS-сертификаты данного УЦ и данного типа более не содержат имени в поле Subject. Это необходимо учитывать в мониторинге. (Обратите, кстати, внимание на этот момент – как ни странно, но мне до сих пор приходится сталкиваться со скриптами и схемами мониторинга, которые по старинке полагаются на значение Subject серверного сертификата при определении имени. Если в сертификате поле Subject пустое, такие скрипты не просто не работают, но часто вообще начинают действовать неверно – потому что пустое значение даёт интересные эффекты при попытках его обработки. Как переделать shell-скрипты, использующие OpenSSL, описано в одной из записок по теме.)
В остальном – работает неплохо. Кроме dxdt.blog, я нашёл применение для шестидневных сертификатов там, где нужен TLS-сертификат для IP-адреса. Так, у меня есть демонстрационный сайт под IP-адресом: https://185.39.19.199/ – там TLS-сертификат обновляется certbot со штатными настройками. Также я использую TLS-сертификаты для IP-адресов на некотором DNS-стенде, где такие сертификаты очень хорошо подходят для авторитативных серверов DNS (DNS over TLS: см., например, тестовый сервис для резолверов dns.1d.pw).
Комментировать »
Я иногда говорю, что к JWT (веб-токену) нужно относиться так, как если бы это был “публичный документ”, что JWT мог быть “написан на заборе”. Речь тут всегда идёт о точке зрения сервера, использующего “внешние” JWT для внутренней аутентификации пользователей. Но всё равно этот момент вызывает у слушателей удивление: как так? ведь это же токен аутентификации, он позволяет получить доступ к сервису, его же нужно держать в секрете! Конечно, нужно держать в секрете, если вы клиент-пользователь и только что этот токен получили. Но если вы реализуете внешний, по отношению к провайдеру токенов, сервер, то можно ли расчитывать на то, что токен клиент “держал в секрете”? Можно ли рассчитывать на то, что получал токен именно тот клиент, который сейчас его предъявил? Правильный ответ: нет и нет, нельзя. Так что нужна совсем другая интерпретация, если вы на стороне сервера, а токен получили даже не от того, кто его выдал – токен вам принёс клиент, который, предположим, и “прочитал его на заборе”.
“Что мы знаем о лисе? Ничего. И то – не все”. Вспомним про JWT. JWT – это токены доступа (JSON Web Token), содержащие различные данные, имеющие цифровую подпись, и представленные JSON-структурой. В JWT может быть записано имя пользователя и его роль, задающая уровень доступа. Данные токена нередко не зашифрованы, а занесены в открытом виде, поэтому их легко прочитать, получив токен. Банальный способ применения JWT – носитель данных авторизации. Есть разновдности токенов по назначению, а перехват того или иного токена, в типовом режиме использования, становится равносилен перехвату роли, записанной в токене. Но эффект перехвата не всегда прямой и ограниченный. Например, при “удачном” стечении обстоятельств, если перехвачен токен “обновления” (refresh JWT), то перехвативший его может “обновить” чужую сессию и получить новые параметры доступа для чужого аккаунта. JWT сейчас едва ли не повсеместно используют в качестве носителя данных в процессах авторизации/аутентификации. Несмотря на то, что сам механизм допускает дополнительные каналы подтверждения подлинности токена сервером, его выдавшим, в подавляющем большинстве случаев – JWT используют напрямую: верят самому токену и только, и хорошо, если корректно проверяют подпись и срок действия.
Пусть токен подписан цифровой подписью. Предполагается, что секретный ключ от данной подписи принадлежит некоторому доверенному провайдеру токенов. Однако, чтобы сформировать доверие технически, можно начать верить в открытый ключ, связанный с провайдером токенов. Сам по себе JWT, что бы в нём ни было написано, доверия вызывать не должен. Правильно: ведь клиент-пользователь мог “прочитать его на заборе”.
Это как раз и означает, что для системы, которая проверяет доступы по токену, используя указанные внутри токена параметры (scope) и значение подписи, всё равно, как этот токен получен. Нельзя строить доверие только на способе получения токена, а тем более, на том, что токен принёс клиент, назвавшийся каким-то там именем.
То есть, буквально, доверие внутри системы, которая проверяет данный токен, образуется потому, что токен содержит валидную подпись от дверенного ключа, а не потому, что токен был получен каким-то “защищённым” образом. Например, с точки зрения этой системы – данный токен вообще можно считать публичным документом, сколь бы парадоксальным это ни казалось. (Ещё раз, данные внутри полей токена могут быть дополнительно зашифрованы (JWE), а чтобы их прочитать – нужно знать подходящий ключ. Но это дополнительная мера.)
Почему это всё может казаться странным? Прежде всего потому, что, в массовых сценариях веба, JWT разрешает доступ некоторому пользователю к некоторой онлайн-системе и разрешает использование некоторых функций. Соответственно, если пользователь свой авторизационный токен потерял, а кто-то этот токен – нашёл (“прочитал на заборе”), то этот “кто-то” может получить и доступ пользователя к целевой системе (полный аналог “авторизационной куки”). От действий пользователя этот доступ уже не зависит. Поэтому, конечно, пользователь должен держать свой токен в секрете. Это очевидно. Возникает ли тут противоречие? “Публичный документ”, который нужно держать в секрете? Как это? Но обратите внимание, что тут нет никаких механизмов дополнительного подтверждения для пользователя: пользователь где-то получил токен; вероятно, там он вводил пароль или ещё как-то авторизовался, но теперь токен действует непосредственно – если внутри токена, в открытом виде, написано, что это пользователь Имярек, значит, в доверяющей системе пользователь с данным токеном станет Имяреком. То есть, противоречия нет. А вся хитрость в том, что это просто так принято: считать JWT секретным и привязанным к пользователю, но без реальных проверок. Проверки возможны – об этом в конце записки.
Важный момент, про который нельзя забывать: от пользователя, авторизующегося при помощи JWT в базовой схеме, даже не требуется доказательство владения секретным ключом от подписи в токене. Считается, что ключ есть у сервиса, который выпускает токен. Соответственно, если подходить строго формально, то и авторизация тут предоставляется ключу сервиса, не пользователю. То есть, всякий может прочитать значения внутри токена (если он не зашифрован) и внешний сервис (не пользователь!) имеет полный контроль над ключом, позволяющим создавать доверенные токены, в том числе, с заданным значением полей. Это ли не “публичный документ”, при прочих равных?
Заметьте, что так как обычный JWT самодостаточен, утащить его у пользователя может и тот сервис, на котором пользователь пытается JWT применить. Другими словами: пользователь получает JWT на одном сервисе, но сам протокол подразумевает, что пользователь потом предъявляет этот токен произвольным другим сервисам, которые токен видят и могут использовать в произвольных целях. То есть, опять возникают признаки “публичного документа”.
Но если интерепртировать JWT как публичный, то, получается, и доступ предоставить можно только тот же, что получает произвольный, неавторизованный пользователь? В идеале – именно так и должно быть (и см. про расширения протокола ниже). Однако на практике – это радикально уменьшает степень полезности JWT. Да, такие “определённо публичные” JWT всё ещё можно использовать как некий инструмент подтверждения происхождения данных, например, в качестве доверенного файла конфигурации: ведь изменить параметры, не зная секретного ключа, не получится. Но от JWT ожидают некоторого прозрачного способа аутентификации “по цепочке”: то есть, какой-то другой сервис пользователя проверил, выпустил подтверждение, отдал его пользователю, и теперь это подтверждение принимается на другом сервисе как эквивалент локальной аутентификации. Удобно. Но не всегда правильно.
Вообще, история с дополнительным ограничением применимости JWT весьма важная. Например, RFC 9449 как раз описывает дополнительный механизм, который позволяет привязать JWT, выданный внешним сервисом, к открытому ключу, секретную часть которого контролирует пользователь, предъявивший JWT. При использовании JWT пользователь предъявляет и доказательство владения собственным секретным ключом. В такой схеме уже не получится использовать только лишь подписанный внешним сервисом JWT. Нужно ещё знать пользовательский секретный ключ. И это как раз полный и верный ответ на трактовку JWT как публичного документа: да, JWT – публичный, но чтобы применить его на сервисе – нужно доказать знание пользовательсткого секретного ключа, поэтому-то в этой схеме “просто прочитать JWT на заборе” уже не достаточно.
Комментировать »
Сейчас на веб-сайтах крупнейших российских банков в TLS появился “сертификат Минцифры”, в том числе, на веб-интерфейсах систем “Личного кабинета”. “Сертификат Минцифры” – это сертификат корневого ключа Национального Удостоверяющего Центра, “сертификат НУЦ”. То есть, для штатного соединения – нужно доверие соответствующим корневым сертификатам (от НУЦ). Из коробки – доверие есть только в “Яндекс.Браузере”. В остальных случаях – нужно добавлять сертификат вручную.
С доверием тут проблема не только в браузерах. Сертификатам этим вообще доверяют не все пользователи. В связи с этим сейчас много где рекомендуется некоторый весьма технический метод установки “сертификатов Минцифры”, но с ограничением по допустимым именам хостов, чтобы сертификаты от данного корня считались валидными только для некоторых имён, предположим, для имён только в зоне .RU, или для имён только в DNS-зоне банковского сайта. Это боязнь атаки типа MITM: технически, всякий УЦ может выпустить сертификат для любого имени.
Речь не про механизмы управления доверием по именам в конкретных браузерах, а именно про уровень TLS-сертификатов и цифровой подписи. Чтобы реализовать ограничения, предлагается “переподписывание” при помощи собственного, локального доверенного корневого ключа, с установлением ограничений в nameConstraints. Схема многим кажется хитрой. И надо заметить, что техническая хитрость в схеме действительно есть. Я не считаю, что это хорошая схема для продвинутого пользователя. Для такого пользователя гораздо лучше – аккуратно создать отдельную копию браузера, со своим списком корней. Поэтому детальных команд я не привожу, но если захотите, то сгенерировать всё нетрудно при помощи OpenSSL (не забудьте только ключи удалить).
Вообще, цель этой записки в другом: объяснить, что это всё означает, почему и как работает. Речь здесь пойдёт про веб-браузеры и TLS в HTTPS.
Итак, упомянутая выше схема “переподписывания” давно известна среди специалистов, она вполне штатная, и называется “кросс-подпись”. Логика алгоритма в том, что открытый ключ из целевого “корневого сертификата”, – обозначим его литерой “Б”, – подписывается ключом доверенного УЦ, а получившийся новый сертификат содержит такой же открытый ключ, как сертификат “Б”, и такое же имя в поле Subject. По такой схеме долгое время в браузерах работал УЦ Let’s Encrypt (да и сейчас есть сертификаты для корневых ключей Let’s Encrypt, выпущенные от других УЦ, это улучшает совместимость).
Почему кросс-подпись работает? Потому что в ходе валидации серверного сертификата цепочка строится по именам (Issuer <===> Subject), а подписи проверяются по открытым ключам из сертификатов цепочки. Часть цепочки – присылает сервер, а доверенный корень – встроен в браузер. Чтобы сертификат был признан валидным, необходимо (но не достаточно), чтобы цепочка пришла к доверенному ключу. Но нет разницы, что это за ключ и откуда он – главное, чтобы он был доверенным. Поэтому прочие данные из TLS-сертификата всегда играют вспомогательную роль, главное, что есть в сертификате – открытый ключ. Поэтому и сертификаты строго называют “сертификатами ключей”.
Предположим, что сервер вернул собственный, оконечный сертификат, а подпись на этом сертификате стоит от ключа промежуточного удостоверяющего центра (УЦ), сертификат данного ключа тоже прислал сервер. Валидирующий сертификаты браузер выбирает сертификат подписывающего ключа, прежде всего, по имени Issuer из подписанного сертификата, потом производится попытка проверки подписи ключом из выбранного сертификата. Если вдруг оказалось несколько сертификатов, подходящих по имени, но с разными ключами, то процедура проверки подписи даст валидный результат только для правильного ключа. Обратите на этот момент внимание – он главный: проверка подписи выполняется при помощи ключа, и доверие, в конечном итоге, выстраивается по ключам. Фокус схемы с кросс-подписью в том, что ваш браузер начинает верить в ключ потому, что доверие этому ключу прямо установлено. И установлено доверие может быть другим корневым сертификатом, а не тем, который предлагается “скачать и установить”. Главное, чтобы открытый ключ совпадал.
Оказывается, этот момент регулярно ускользает из поля внимания даже технически продвинутых пользователей, а в результате – теряется понимание процесса.
Рассмотрим очень подробный пример.
Пусть сервер адресуется именем example.com. Для example.com выпущен оконечный (серверный) сертификат от ключа промежуточного УЦ под названием Interm-CA-1. Для открытого ключа этого УЦ Interm-CA-1 выпущен сертификат “корневым УЦ” Root-CA-1. И открытый ключ Root-CA-1 встроен в браузер. Браузер доверяет открытому ключу Root-CA-1. Этот открытый ключ непосредственно указан в сертификате Root-CA-1. Тогда браузер выстраивает цепочку example.com <- Interm-CA-1 <- Root-CA-1, проверяет подписи от Root-CA-1 на Interm-CA-1, а от Interm-CA-1 на example.com и, если всё сошлось, распространяет доверие по цепочке до сертификата example.com. Это обычный способ, без кросс-подписи.
Теперь представьте, что в браузере есть и Root-CA-2, тоже доверенный. Пусть Root-CA-2 выпустил и подписал сертификат для того же открытого ключа, который указан в сертификате Root-CA-1. “Обычный” сертификат корневого ключа Root-CA-1, который упоминался выше, – это самоподписанный сертификат, то есть, подпись в нём от того же ключа, открытая часть которого указана в сертификате. Новый сертификат, выпущенный для ключа Root-CA-1 не является самоподписанным – его подписал Root-CA-2, используя другой ключ.
Обратите внимание: открытый ключ в этом новом сертификате – тот же, что и в самоподписанном сертификате корневого ключа Root-CA-1. Это подпись другая. Соответственно, этот открытый ключ позволит успешно проверить подпись, поставленную Root-CA-1 на сертификате Interm-CA-1 из цепочки, описанной выше. Более того, когда УЦ Root-CA-2 генерировал сертификат для ключа Root-CA-1, то этот УЦ и в качестве имени Subject сертификата указал Root-CA-1. Но Issuer – отличается: здесь стоит Root-CA-2 (в самоподписанном исходном и Issuer, и Subject – были Root-CA-1). Браузер верит ключу Root-CA-2. Теперь возможна другая цепочка: example.com <- Interm-CA-1 <- {Root-CA-1} <- Root-CA-2. Цепочка ведёт к Root-CA-2, он доверенный. Сертификат в фигурных скобках {Root-CA-1} – это сертификат для того же открытого ключа, от Root-CA-1, но выпущен он Root-CA-2. А раз это тот же ключ, то и для сертификатов, которые в цепочке находятся левее {Root-CA-1} ничего не поменялось – доверие транслируется точно так же. Это и есть кросс-подпись.
В схеме кросс-подписи больше не нужен доверенный корневой самоподписанный сертификат Root-CA-1. Его не нужно ставить в браузер вообще, потому что доверие транслируется от Root-CA-2 через кросс-подпись, поставленную на ключе, а не “на исходном сертификате”, как почему-то иногда пишут. Нет, исходный корневой сертификат не “переподписывается” – из него просто берётся открытый ключ, а далее доверие этому ключу образуется при помощи его подписывания собственным, локальным корневым ключом. И в браузер добавляется доверие этому, корневому ключу. Естестсвенно, необходим {Root-CA-1} (в фигурных скобках), выпущенный Root-CA-2. Этот сертификат (в фигурных скобках) локальный, его не пришлёт сервер. Поэтому сертификат придётся добавить в браузер (если для этого сертификата установить флаг доверия, то не нужен уже Root-CA-2, кстати. Но см. ниже про целевые ограничения – их нельзя утрачивать.)
Где же здесь ограничения? Они в nameConstraints. В TLS-сертификатах есть штатный способ, который позволяет описать ограничения по именам, для которых применим ключ из сертификата. Обратите внимание на важный момент: это механизм описания, он вовсе никак не позволяет “реализовать ограничение”. Реализация – остаётся на стороне валидатора сертификатов. То есть, если браузер применяет ограничения из блока сертификата nameConstraints, то сертификат не будет считаться валидным для имён, за пределами списка, если не применяет – будет. Современные браузеры nameConstraints обрабатывают и ограничения применяют. В частности, Firefox действует даже строже, чем предписывают RFC, касающиеся этих ограничений.
Механизм ограничения валидности довольно прост: в поле nameConstraints перечисляются наборы DNS-имён для которых разрешено или запрещено применять ключ при проверке подписи. Прежде всего, данное поле предназначено для сертификатов ключей УЦ. То есть, для ключей, от которых выпускаются другие сертификаты. При корректном применении ограничения должны действовать по всей цепочке вниз. Например, если в корневом сертификате указано ограничение “разрешено только для example.com”, то валидатор, следующий ограничениям, не примет сертификат от этого корня для example.net. Цепочка проверки при этом может включать несколько промежуточных сертификатов. Ограничения по именам применяются и тогда, когда в сертификате этих имён много: все имена должны быть разрешены, иначе валидация не пройдёт. То есть, при правильной реализации, метод весьма действенный.
Теперь, если мы подписываем кросс-подписью ключ другого УЦ, то мы можем указать нужные ограничения в сертификате, который подписываем. Ограничения перечисляются в nameConstraints. В принципе, ограничения можно указать и сразу в локальном сертификате корневого ключа. В качестве состава ограничений может быть как только конкретный домен верхнего уровня, так и конкретные DNS-имена веб-сайтов. Тогда браузер посчитает невалидными оконечные сертификаты, выпущенные от исходного корневого ключа, но для имён, которые не входят в разрешённый список. Предполагается, что это противодействует потенциальным MITM-атакам: “ограниченный” корневой сертификат уже не позволит браузеру посчитать валидным оконечный сертификат, выпущенный для, условно, google.com. Заметьте, впрочем, что у Chrome и Google есть специальные меры, отслеживающие подобную подмену без всяких nameConstarints и собственного локального корня. При этом локальный корень, налаженный по описанной схеме в том же Chrome, данные меры поломает, поскольку всё будет выглядеть так, как если бы в систему установлен “сертификат корпоративного УЦ”, а для таких случаев многие способы детектирования подмены серверных ключей работают не так строго. Это один из неочевидных аспектов использования данного решения.
Итак, схема сводится к следующим шагам: 1) генерируем собственный корневой секретный ключ и сертификат для этого ключа с ограничениями по именам в nameConstraints; 2) встраиваем в браузер открытую часть данного ключа в качестве доверенного; 3) выпускаем от этого корневого ключа сертификат кросс-подписи для ключа из “сертификата Минцифры”, совпадающий по имени Issuer с “оригинальным”, возможно, повторяем тут ограничения по именам, добавляем этот сертификат тоже в доверенные. “Сертификат Минцифры” – добавлять не нужно, уже добавлен ключ из него. Всё. Теперь браузером начинают считаться доверенными сертификаты только на сайтах, подходящих по именам.
Какие есть подводные камни на этом направлении? Самые разные. Форма и размер этих камней – определяются теми рисками, с которыми вы попытались бороться. Прежде всего: наличие локального “ограниченного” корня вовсе не отменяет установления TLS-соединения. Нет. Браузер всё равно будет подключаться к произвольным сайтам, выполнять начальную стадию TLS-соединения, и лишь получив в ответ сертификат, ключ из которого сходится к нашему “ограниченному корню”, применять ограничения по именам и выдавать ошибку, если ограничения не позволяют принять сертификат. Про это нельзя забывать: собственный корень не ограничивает подключение и обработку сертификатов, он управляет только итогом валидации.
Заметьте, кстати, что если на локальном компьютре установлен антивирус, перехватывающий TLS-соединения браузера, то все описанные манипуляции с сертификатами никак не повлияют на реальное положение дел с валидацией.
Добавление локального корневого сертификата в доверенные означает, что если соответствующий секретный ключ утечёт, то тот, кто его получил, сможет подменять сертификаты для всех вариантов имён, подходящих под ограничение nameConstaraints. Если это сайты банков, то сразу возникает весьма неприятный риск. Поэтому, как минимум, следует защитить (лучше – уничтожить) такой “подменный” секретный ключ. Этот момент тоже постоянно упускают из виду.
Соответственно, если идея “ограничений” состояла в том, чтобы ограничить применение “сертификатов к сайтам”, то в данной схеме это не так, сертификаты продолжают применяться, они лишь не считаются валидными. Поэтому вариант с отдельным браузером, под конкретные сайты, имеющим собственный набор корневых сертификатов, в который либо добавлен вручную оригинальный корень, либо собственный корень для “кросс-подписи”, может оказаться сильно лучше.
Комментировать »
Ближайшее будущее в области TLS-сертификатов для веба – это сертификаты на хеш-деревьях. Я писал об этом неоднократно. Ещё одно подтверждение: черновик политики Google по включению в список доверенных удостоверяющих центров (УЦ) веб-браузера Chrome. Этот черновик касается постквантовых криптосистем цифровой подписи (или, как их ещё обозначают, “квантовостойких” криптосистем). В контексте данной программы доверенных УЦ Chrome – это криптосистема ML-DSA (и только). Но главное тут не тип криптосистемы, а то, что политика допускает исключительно схему с хеш-деревьями, с MTC (Merkle Tree Certificates). Соответственно, УЦ, не поддерживающие MTC – в программу даже податься не смогут, вне зависимости от других параметров. MTC, с точки зрения УЦ, совсем другая история, если сранивать с имеющимся сейчас вариантом.
Этот вариант, – хеш-деревья, – алгоритмически близок с реализации Certificate Transparency (CT). Концептуально, MTC – это перенос CT на сторону УЦ. Поэтому в черновике политики прямо сказано, что на начальном этапе включение в “квантовостойкие корни браузера” будет доступно только для тех организаций, которые уже поддерживают работоспособный лог CT (то есть, запустили такой лог до 1 февраля 2026 года). К таким организация, естественно, относятся Let’s Encrypt, Cloudflare и Google (но не только эти).
Основные особенности MTC в TLS: “бесподписные” сертификаты – то есть, буквально, серверные TLS-сертификаты в которых вместо подписи – доказательство включения в хеш-дерево; очень короткий срок действия сертификатов – предпочтение будет отдаваться “шестидневным” сертификтам (и более “коротким”). “Бесподписная” часть – экономит трафик, поскольку сильно уменьшает размер сертификата в байтах, но также привязывает клиента к сервису, с которого нужно скачивать обновления дерева. Короткий срок действия – привязывает к точке выдачи сертификатов (и, таким образом, к провайдеру данных дерева) ещё и операторов TLS-серверов.
Комментировать »
В продолжение записки про метки на выдаче LLM-систем, которые должны позволять атрибутировать текст (или другой тип контента), как сгенерированный ИИ/LLM. Тут есть несколько нехороших моментов.
Момент первый. Если определять такие метки будет тот же провайдер, который обеспечивает LLM, то получается существенное усиление позиции этого провайдера: он сможет по собственному разумению приписывать своей системе произвольные тексты.
То есть, LLM-провайдер захватил и использовал в своих целях практически весь контент, до которого смог дотянуться (в том числе, страницы веб-сайтов), а теперь ещё и сможет маркировать контент как “свой”, придавая, тем самым, дополнительную окраску различным публикациям. Тут важно понимать, что это только кажется, будто тут борбьба идёт за то, что некие пользователи распространяют “сгенерированный контент” как “подлинный”. Нет. Вопрос подлинности контента остаётся в стороне. Выдача LLM тоже может быть подлинной. Банальный пример – это, например, публикация, основная часть которой – разбор особенностей этой самой выдачи. Есть и небанальные примеры: цитирование и синонимизирование текстов LLM-генератором.
Так что речь не про произвольную атрибуцию, а про навязываемую окраску: и контент был, буквально, отобран и захвачен через синонимизацию, и результат захвата теперь использовать не позволяется без обязательного окрашивания тем же провайдером того же самого сервиса, в который этот контент утёк. И это всё в ситуации, когда без крупнейших LLM-систем уже практически не обойтись, поскольку и интернет-поиск сломали, и всё вокруг заливается выдачей этих систем. Ещё раз: это, конечно, работает только в том случае, если обнаружение меток и аутентификацию таки оставят за провайдерами LLM-сервисов, а сам метод детектирования не будет подразумевать непрерывного независимого аудита (хотя, кого такой аудит пугает? и где же его “независимость”?).
Момент второй. Что делать, если вполне себе авторский текст, написанный человеком, а не сгенерированный LLM, тем не менее, детектор меток записывает за LLM? То есть, автору говорят – нет, это всё сгенерировано.
– Вы просто переписываете “Википедию”!
– Нет, это не так, это редакторы “Википедии” берут мои статьи за основу.
Ошибки атрибуции, понятно, не то что возможны, они – обязательно будут. Про эти самые ошибки до сих пор написано в тех же самых интерфейсах лидирующих LLM-сервисов. Более того, если метка не является криптографической, то подготовленному человеку не составит особого труда написать текст, который будет определяться как сгенерированный данной LLM. То есть, тут уже получается такое “навязывание метки”. Можно подумать, что это ерунда. Но нет – кто там знает, что “такое сомнительное” могут “навесить” на сервис? Тоже интересный момент.
– Можно ли подзарядить мой смартфон от твоего портативного аккумулятора?
– Конечно. Подключай.
– Спасибо! Ого, а что это там замигало?
– Это данные передаются.
– Да? Ну, ладно, мне нечего скрывать из того, что есть в смартфоне.
– А кто сказал, что данные считываются из смартфона? Напротив, они сейчас туда загружаются. И, кстати, теперь тебе есть, что скрывать.
Момент третий. Что считать достаточной “степенью генерирования”? Подходит ли дорисованная на ночную фотографию пейзажа Луна? Это достаточное вмешательство, чтобы стать “генерированием”? А если Луну дорисовало ПО фотокамеры в смартфоне? А если это сработал “фильтр” в программе для обработки цифровых фотографий, и Луна не дорисована полностью, но “улучшена”? Считается ли исправление орфографических ошибок в тексте достаточным признаком? Сколько ошибок можно исправить автоматом, чтобы деятельность автомата посчиталась как генерирование LLM? Есть ли разница между “орфографией” на буквах и “рисованием” на пикселах? Сколько можно исправить пикселов? Заметьте, что практически всякое установление границ и лимитов на этом направлении тут же приводит к размытию и лимитов, и границ.
Но, конечно, хуже всего выглядит то, что LLM-првайдеры получают возможность помечать как “свой” контент, полученный на основе творчества человеческих авторов, а позже лишь синонимизированный. И на основании такого окрашивания будет выстраиваться отношение к исходным идеям и публикациям. Максима “Компьютер не может ошибаться” приведёт к тому, что LLM-сервис, на основании значения метки, станут считать первоисточником. Причём, вот тут уже и не требуется, чтобы метки обрабатывал тот же провайдер, который предоставляет LLM-сервис.
Comments Off on Метки и окрашивание контента от LLM-систем
Кстати, что касается обнаружения отзыва серверных TLS-сертификатов. Ещё раз подчеркну – речь здесь об оконечных, о серверных TLS-сертификатах. С сертификатами УЦ – ситуация отличается. Итак, для оконечных сертификатов, сейчас, согласно требованиям CA/B-форума, есть три базовых способа публикации статуса сертификата и несколько вариантов их комбинирования:
1) публикация CRL;
2) OCSP-респондер;
3) ничего (то есть, нет точки публикации информации о статусе сертификата).
Итак, первый вариант, CRL: файлы CRL выкладываются на точку раздачи, доступную по HTTP, откуда их можно скачивать; URL указывается в составе сертификата (отдельное поле). В ряде случаев применяется различный “шардинг” и множественные URL. Например, Let’s Encrypt использует для одного и того же поколения сертификатов и промежуточного УЦ большое количество разных имён CRL (они именованы порядковым номером: 1, 2, 3, …, 128). В сертификате может быть указано несколько точек раздачи CRL, с разными URL. Это важный аспект.
Второй вариант, OCSP: OCSP давно перевели в разряд опциональных, но данный протокол всё равно используется; и если используется, то публикуется точка доступа к OCSP-респондеру (на практике, транспортом тоже будет HTTP), URL указывается в сертификате (отдельное поле, отличается от поля для CRL). Может быть несколько URL OCSP.
Третий вариант, самый интересный: в сертификате вовсе не указано способа получения информации о статусе. Такое уже довольно давно допускается, но только для “короткоживущих” (short-lived) сертификатов. Сейчас, “короткоживущий” – это со сроком валидности не более семи суток (604,800 секунд). Поэтому, например, в шестидневных сертификатах Let’s Encrypt может вообще не быть ни CRL, ни OCSP. Ну, OCSP вы там точно не найдёте – в Let’s Encrypt давно перестали его предоставлять; а вот CRL – пока что найти можно, но заметьте, что это опционально.
Теперь, что касается комбинирования. В сертификате всё ещё может быть указан адрес OCSP-респондера, но не указан адрес CRL! То есть, встречаются корректные и валидные сертификаты, статус которых только по OCSP возможно определить, адреса точки раздачи CRL в них нет вовсе. Могут быть указаны и OCSP, и CRL. И может быть только CRL. То есть, если сертификат не “короткоживущий”, то CRL является обязательным, но только в том случае, если нет OCSP (который опционален).
В рамках определения статуса сертификата нужно аккуратно обрабатывать все варианты. Например, если в сертификате указано несколько точек раздачи CRL, то тот факт, что в CRL, полученном от одной из точек, серийного номера сертификата нет, не означает, что сертификат не отозван: его серийный номер может присутствовать в другом файле CRL. Проверять отсутствие нужно по всем CRL. Когда указан OCSP-респондер (или несколько), то нужно и его тоже проверить, если сертификат не нашёлся в CRL.
Комментировать »
В Cloudflare на днях обновили свой сервис мониторинга логов Certificate Transparency (CT). Мониторинг отслеживает публикацию в логах (пре)сертификатов для заданного доменного имени. Напомню, что в прошлом году ни наличие сервиса мониторинга, ни наличие собственных логов CT, не помогли Cloudflare в течение нескольких месяцев выявить неавторизованный выпуск TLS-сертификатов для собственного же сервиса 1.1.1.1 (один из самых известных сервисов Cloudflare). Возможно, какие-то выводы были сделаны. Однако в этом контексте текущее обновление сервиса мониторинга CT выглядит ещё более странным. Дело в том, что это обновление отключает вывод оповещений о сертификтах, выпущенных системами Cloudflare. И делает это при помощи фильтра по открытым ключам.
То есть, если кратко, то клиентам, использующим веб-фронтенд Cloudflare и мониторинг CT, в этот самый мониторинг больше не будут приходить уведомления о том, что для их домена сертификат выпущен Cloudflare в рамках работы веб-фронтенда. Озвучиваемая причина: сертификаты выпускаются часто (у них короткий срок действия), оповещения дублируются, множатся, а их большой поток запутывает пользователя, который, в результате, перестаёт реагировать на подобные оповещения вообще. (Кстати, в истории с 1.1.1.1, “большое количество оповещений” прямо названо среди причин, по которым неавторизованные сертификаты не обнаружили своевременно – тут у Cloudflare все последовательно.)
Различать предлагается не сертификаты, а ключи. Так что сервис мониторинга CT больше не будет присылать уведомления об обнаружении в CT-логах серверных сертификатов, если эти сертификаты содержат тот же открытый ключ, который был сгенерирован Cloudflare для использования на TLS-прокси в сервисе веб-фронтэнда. И это весьма важный момент. Который, тем не менее, в сообщении Cloudflare освещается как-то однобоко. Да, по открытым ключам различать сертификаты удобнее, чем по отпечаткам полного сертификата. Я и сам так рекомендую делать, это здравый подход. Когда применяется правильно. Но нельзя забывать, что для выпуска сертификата Удостоверяющему Центру (УЦ) не нужен секретный ключ, соответствующий открытому ключу клиента.
То есть, то, что Cloudflare отслеживает и фильтрует сертификаты по ключу, не означает, что отслеживаются только сертификаты, выпущенные по запросу систем Cloudflare. Это совсем разные вещи, но про это Cloudflare не сообщает. Поскольку выпуск сертификата не требует секретного ключа, то, технически, какой угодно УЦ может выпустить сертификат для того же серверного открытого ключа, что использует и Cloudflare. Однако мониторинг CT, если верить описанию, этот сертификат не покажет. Проверка подписи в CSR и пр. – это, да, это всё привычные шаги, но, ещё раз, технически они никак на выпуск сертификата не влияют.
Конечно, такой выпуск сертификата для произвольного ключа – возможность весьма теоретическая, не поспорить: да, для выпуска секретный ключ не нужен, но, как минимум, чтобы использовать подобный “подменный” сертификат – тут секретный ключ уже потребуется. Это, однако, не отменяет странной подмены понятий: совпадающий открытый ключ – вообще никак не означает, что сертификат был выпущен по запросу систем Cloudflare, утверждать такое – ошибка.
Естественно, мониторинг CT с подобным фильтром “по ключам” в принципе не сможет проинформировать о некоторых критических событиях. Например, если скомпрометирован аккаунт в Cloudflare и кто-то выпускает “левые сертификаты”. Да, тут можно возразить, что если скомпрометирован аккаунт, то тогда и мониторинг можно отключить. Да, можно. Но не всегда аккаунт скомпрометирован полностью. Дело в том, что авария или взлом на стороне систем Cloudflare – тоже выпадают из новой версии мониторинга, а между тем, тут уже полезно было бы оповещение: потому что “сломаться” может и лишь та система, которая генерирует сертификаты, например.
Как именно отпечатки ключей используются? Возможно ли их “просачивание” между аккаунтами? Непонятно. Если такое возможно, то Cloudflare может использовать тот же открытй ключ, но для разных имён и, соответственно, разных сертификатов, хотя бы и по ошибке. Сертификаты будут опубликованы в CT-логах, но фильтрация по значению ключа такое не покажет.
Не менее интересно и то, что, если скомпрометирован сам фильтр, то можно добавить туда “нужные ключи” и – мониторинг перестанет выводить новые сертификаты. Ну или вообще там в результате атаки будет создан поток для добавления “правильных ключей” – такое нынче тоже нельзя исключать.
В общем, получилась подмена базовой концепции. Формулировка базового вопроса, стоящего за подобным мониторингом CT, такая: разрешил ли администратор имени выпуск этого конкретного сертификта? Но, получается, что её “незаметно” подменили на другую: узнаёт ли сервис Cloudflare данный открытый ключ из сертификата? Почувствуйте, как говорится, разницу.
Всё это, понятно, не делает мониторинг бесполезным, но всё же. Остаётся надеяться, что сделают флаг в настройках – “Показывать все сертификаты”.
Комментировать »
Недавно вышел документ RFC 10024 (обратите внимание: нумерация перевалила за десять тысяч). Этот RFC вводит идентификаторы для гибридов криптосистем обмена ключами в TLS 1.3. Это гибриды из классических и посквантовых криптосистем. В роли классических – выступают X25519 и ECDH, а в роли единственной постквантовой – ML-KEM. То есть, формально закрепляются следующие сочетания: X25519 + ML-KEM-768 как X25519MLKEM768 (0x11EC), ECDH/P-256 + ML-KEM-768 как SecP256r1MLKEM768 (0x11EB), и ECDH/P-384 + ML-KEM-1024 как SecP384r1MLKEM1024 (0x11ED).
При этом в качестве рекомендуемого (recommended) набора отмечен только X25519MLKEM768, варианты с ECDH – содержат значение N в поле “Recommended”. (Тут нужно оговорить, что флаг Recommended – это штука, назначаемая внутри IANA/IETF, и имеющая особенную трактовку; как минимум, тот факт, что ML-KEM стандартизована NIST, не означает, что IANA/IETF автоматически поставят флаг “рекомендуется”, тем более, что тут речь о гибридах; но и делать вывод, что нельзя использовать системы, у которых “Recommended: N” – тоже неверно: тогда бы и смысла в подобных RFC не было бы.)
Что здесь означают числа? В X25519 – это 2^255 – 19, модуль, задающий максимальную разрядность для этой криптосистемы; X25519 – массово используемый вариант протокола Диффи-Хеллмана (DH) на эллиптической кривой. P-256 и P-384 – две разных эллиптических кривых (отличных от используемой в 25519), на которых работает “типовой” протокол DH. P-256, которую также называют SecP256r1, имеет разрядность 256 бит, а P-384 (SecP384r1) – 384 бита. Математически, реализации DH на P-256 и P-384 – абсолютно идентичные, разные только кривые, а DH в версии X25519 тут в некоторых математических деталях отличается (распростраено мнение, – в том числе, среди специалистов, – что как раз эти отличия и делают реализации X25519, в целом, надёжнее и более стойкими, чем для DH на P-256/P-384).
ML-KEM тут фигурирует с двумя наборами параметров: 768 и 1024. Оценка стойкости ML-KEM – штука совсем сложная, поэтому тут только отмечу, что, несмотря на такие значение, ни 768, ни 1024 – как-то “линейно” с битовой стойкостью или эффективной разрядностью не связаны, но 1024, согласно спецификации, считается более стойким набором параметров. Поэтому для более стойкой кривой P-384 и выбран более стойкий вариант ML-KEM-1024.
Я не тестовом сервере tls13.1d.pw давно поддерживаю X25519MLKEM768 и SecP256r1MLKEM768, а вот P-384 пока не добавил.
Комментарии (2) »
Иногда приходится слышать, что, мол, не нужно на уровне гипервизора применять различные фильтры и ограничения для сетевого трафика виртуальных машин, исполняемых под управлением этого гипервизора и, соответственно, гостевых операционных систем (ОС). Дескать, трафик всё равно фильтруется на стороне гостевых ОС, мы там настраиваем правила в Netfilter. А если сломали “гостей”, значит – уже и так сломали. Это, конечно, неверный подход.
Фильтрация, как мера обеспечения информационной безопасности, необходима и на стороне гипервизора. Речь здесь не столько про “вредоносный трафик”, – что бы это ни значило, – а про алгоритмы различных практических атак, направленных на получение управления и виртуальной машиной (VM), и, следом, самим гипервизором (такое возможно, не сомневайтесь). И, конечно, тот факт, что используются “виртуальные интерфейсы”, поэтому те же сетевые пакеты, которые попадут в ядро гостевой ОС, проходят и через ядро ОС гипервизора, вовсе не отменяет необходимости фильтрации гипервизором. Вот вам несколько поводов для внедрения фильтров и контроля сетевого доступа на уровне гипервизора.
1. В ОС на гипервизоре не оказалось нужной уязвимости, для эксплуатирования которой требуется отправка сетевых пакетов. Ну, то есть, не за что зацепиться. А вот в ОС, исполняемой в виртуальной машине, уязвимость есть. Если пакет не добрался до виртуальной машины, то пакет не повредил ни машине, ни гипервизору. Это, пожалуй, самая простая, банальная причина применять фильтры на уровень выше, чем находятся внутренние интерфейсы VM.
2. Представьте, что пакет, адресованный “гостевой системе” (внутри VM), служит для запуска уже подготовленного внутреннего процесса получения управления, для запуска транспорта атаки. Например, на виртуальной машине уже налажено некоторое состояние, следующим шагом которого будет выход в гипервизор (ну, предпоолжим самый худший сценарий). Для запуска этого шага нужно, чтобы на виртуальном интерфейсе появился пакет с определённой структурой, позволяющий запустить процесс и проэксплуатировать всю цепочку уязвимостей. (То есть, для того, чтобы уязвимости сработали, уже всё настроено, но настройка бесполезна без внешнего пакета с определёнными свойствами. Отправка локального пакета, внутри VM, проблему не решает.) Если пакет не проедет через фильтр на уровне гипервизора, то ничего не сработает и уцелеет, как минимум, гипервизор, как максимум – и VM тоже уцелеет.
3. Казалось бы – сетевые пакеты такие же. Однако на стороне гипервизора они обрабатываются фильтрами “чуть иначе”. Пусть у нас есть некая “дефектная” ветка, позволяющая что-то сломать в результате обработки “кривого” пакета. Но эта ветка требует, чтобы пакет был доставлен на “гостевой интерфейс”. Поэтому пакет, отброшнный фильтром раньше, чем начала работать системная реализация “доставки на гостевой интерфейс”, не приводит к срабатыванию “дефектной” ветки. (Это, кстати, вполне себе актуально для разных типовых “переполнений буфера”.)
4. Предположим, что нужное для успешной атаки состояние системы (неважно какой системы: в VM или гипервизора), образуется только после определённого количества “перекладываний” пакета между фильтрами и внутренними очередями (например, нужно несколько последовательных вызовов фильтрующего “хука”). Если пакеты отбрасываются, то состояние оказывается недостижимым, а целевая система – сохраняет, что называется, штатной состояние: атака не работает.
Это, естественно, далеко не все причины. Например, тут вообще не затронуты обратные сигналы (то есть, пакеты, отправляемые из гостевых систем) и взаимодействие между VM, когда из одной можно перепрыгнуть в другую, соседнюю.
Комментировать »
В Anthropic пишут, что в августе начнут (или уже начали) добавлять специальные “метки происхождения” в тексты и другие материалы, которые генерирует ИИ-LLM Claude. Метки должны обозначить то, что текст сгенерирован данной LLM (ну или сгенерирована картинка, или ещё что-то).
Понятно, что подобные невидимые метки там могли добавлять и раньше. Как минимум, метки полезны для того, чтобы повторно не загружать в LLM выдачу этой же LLM. Метки можно сделать полностью скрытыми, чтобы для обнаружения нужно было знать секретный ключ, а если сгенерированного материала достаточно много (в битах), то метка может переживать и редактирование (если это, конечно, не просто поле в “метаданных” файла). Очередной заход, насколько можно понять, подразумевает “видимые” метки, то есть, метки, как минимум, пригодные для обнаружения заинтересованными сторонами кроме провайдера LLM-сервиса – в этом весь смысл. Объясняют всё требованиями европейского законодательства, конечно.
Вообще, с подобными, – но невидимыми, – метками интересен совсем другой аспект: грамотно сконструированные метки позволят определять не просто LLM-источник, но конкретное происхождение текста (не только текста, понятно: то же применимо и к картинкам, и к видеофайлам). Это даёт мощный механизм влияния. Я писал об этом в 2024 году:
Скрытые метки (“водяные знаки”), добавляемые в тексты, которые генерируют ИИ LLM, могут содержать много дополнительной информации. Вообще, в метку можно поместить и уникальный идентификатор пользовательской сессии, внутри которой этот текст был выдан системой. То есть, получается, что какой-то пользователь привычно использовал очередной сервис GPT для генерирования текста, который потом подредактировали и опубликовали в Сети. Бот провайдера сервиса GPT этот текст позже находит и связывает с пользовательской сессией. Теперь провайдер сервиса знает, какие пользователи для чего тексты генерируют. Соответственно, может вносить нужные изменения, оказывая прямое влияние на результат.
Комментировать »
Появилась новая публикация (Daniel R. Simon), предлагающая квантовый алгоритм, взламывающий – теоретически! – криптосистемы типа ML-KEM/ML-DSA за полиномиальное время (то есть, атака предложена на задачу, лежащую в основе предположения о стойкости, в том числе, ML-KEM/ML-DSA, но подходит не только для них). Для работы алгоритма потребуется подходящий квантовый компьютер – уже этим многое сказано. Однако пока что и сама работа опубликована в статусе черновика, о чём там прямо сказано. То есть, скорее всего, – найдутся ошибки.
(У меня самого в этом направлении квантовых изысканий всё время вызывает сомнение ловкое “превращение вероятностей”, которые то идут потоком амплитуд, – это чисто квантово-механическая штука, обычно, описываемая при помощи комплексных чисел, – то вдруг становятся привычными вероятностями. Но я пока сформулировать это сомнение на более или менее понятном языке не могу, так что оставлю в скобках. Тем более, что это всё применимо и к алгоритму Шора.)
Если же ошибки в упомянутой выше работе не найдутся быстро, то это будет означать, что для атак на постквантовые алгоритмы предложен квантовый алгоритм. Это занятно. Но в этом нет никаких противоречий: почти вся практическая современная постквантовая криптография строится из предположения стойкости к алгоритму Шора, а вовсе не к мифическому “перебору на квантовом компьютере”, который придумали в газетах и о котором едва ли не повсеместно в тех же газетах сейчас пишут. Это всё, без всяких оговорок, прямо применимо к ML-KEM/ML-DSA: никто не доказал, что нельзя разработать квантовый алгоритм для эффективного взлома этих криптосистем – есть только рассужения о том, что алгоритм Шора к ним не подходит (если вдруг вы хотите в нескольких словах узнать почему не подходит, то вот: потому что там, в атаке на ML-KEM/ML-DSA, нельзя прямо применить алгоритм нахождения периода некоторой функции). Но специальный квантовый алгоритм, отличный от алгоритма Шора, вполне может существовать. Даже так – скорее всего, такой эффективный алгоритм есть, его только нужно найти и описать, а это очень сложно.
Что будет означать появление описания квантового алгоритма, эффективно взламывающего ML-KEM/ML-DSA и другие криптосистемы под собирательным обозначением “на решётках”? Это точно не приблизит к реальности сами универсальные квантовые компьютеры, но зато создаст вполне себе хорошее обоснование для того, чтобы либо улучшать стойкость ML-KEM/ML-DSA и прочих “решёточных” криптосистем, либо переходить на другие криптосистемы. И это будет весьма забавно: для атаки на постквантовые криптосистемы предложены новые теоретические квантовые алгоритмы, поэтому нужны суперпостквантовые криптосистемы, устойчивые и к алгоритму Шора, и к новому алгоритму “Имярек”.
Посмотрим, в общем, что там предложат. Так или иначе, но считать ML-KEM/ML-DSA неприступными – точно ещё рано.
(Update, 17/08/2026: в свежей работе (Aparna Gupte, Seyoon Ragavan, Mark Zhandry) утверждается, что квантовые алгоритмы данного типа, – как предложенный в исходной публикации, – вообще не позволяют извлечь информацию в количестве, необходимом для взлома криптосистемы.)
Комментировать »
Новый