Ресурсы: техническое описание TLS, LaTeX - в картинки (img), криптографическая библиотека Arduino, шифр "Кузнечик" на ассемблере AMD64/AVX и ARM64
В свежем Chrome 155 включена поддержка подписей ML-DSA в TLS-сертификатах (в том числе). Но не для корневых ключей, входящих в общую глобальную иерархию доверенных ключей, которая “коробочная” – то есть, не для WebPKI, а только для внутренних систем, с добавлением корневых ключей вручную: на сайтах и “из коробки” отдельные TLS-сертификаты с ML-DSA пока не планируются, а планируется, что будет добавлена сразу схема на хеш-деревьях.
ML-DSA – это постквантовая криптосистема цифровой подписи. У DigiCert есть тестовый веб-сайт, где используется цепочка сертификатов с ML-DSA-подписями. Так что посмотреть на такие сертификаты можно даже браузером. Но без автоматической валидации. К сожалению, оконечный сертификат на веб-узле по ссылке не содержит SAN: вообще говоря, по современным спецификациям, да с точки зрения браузера, такой сертификат не валиден для веб-узла в TLS, безотносительно ML-DSA, поскольку строго требуется указание имени именно в SAN, а Subject/CN – давно не используется для проверки DNS-имени (но можно добавить исключение, конечно).

Другими словами: автоматически перейти на подобные сертификаты для веб-сайта пока что не получится, и не только потому, что никакой хорошо известный УЦ ещё их не поддерживает, но и потому, что не поддерживают браузеры. Но сделать собственную цепочку TLS-сертификатов с ML-DSA (и, кстати, CRL тоже), а потом попробовать, что произойдёт в Chrome свежей версии – уже можно: средства и спецификации есть.
И, ещё раз, не забывайте, что внедрение именно такого варианта в “общем вебе” даже не планируется. Доверенные УЦ сразу перейдут на MTC – сертификаты на хеш-деревьях. Там тоже используется ML-DSA, но схема совсем другая, и она позволяет вовсе не указывать подписи в самих оконечных (серверных) сертификатах.

Комментировать »
Обычный вариант атаки MITM для TLS подразумевает, что у перехватывающего узла (прокси) есть секретный ключ от валидного серверного сертификата (ну и сам сертификат, естественно). Тогда перехватывающий узел выдаёт себя за настоящий TLS-сервер в сторону клиента, и за клиента – в сторону настоящего TLS-сервера.
В IP-сети всякий промежуточный узел может ответить вместо настоящего, так что в сетевом смысле атака не самая трудная. Получается, что TLS-сессия установлена не между клиентом и сервером, а превратилась в две TLS-сессии: одна – от клиента до перехватывающего узла, вторая – от перехватывающего узла до настоящего сервера. Промежуточный узел принимает трафик в обе стороны и видит его в открытом виде, так как TLS-соединение между клиентом и настоящим сервером не установлено, трафик никто не защищает.
На что тут влияет клиентская аутентификация в TLS? Вот на что: штатный способ аутентификации TLS-клиента сервером, – на этапе установления соединения, – подразумевает, что клиент подписывает все TLS-сообщения, которые были переданы до настоящего момента, а это означает, что перехватывающий узел не сможет получить корректную подпись для своей сессии в сторону подлинного сервера. Чтобы это сработало, сервер должен поддерживать клиентскую аутентификацию, конечно.
То есть, буквально, TLS-клиент при помощи секретного ключа подтверждает, что получил некоторые TLS-сообщения с конкретным содержанием (там побайтово все сообщения подаются на вход хеш-функции). В случае MITM, клиент подпишет те сообщения, которыми обменивался с перехватывающим узлом, с прокси. Но состав этих сообщений отличается от сообщений, которыми перехватывающий узел обменялся с подлинным сервером (см. ниже объяснения). Подлинный сервер же – видит лишь сообщения от перехватывающего узла (и свои собственные), соответственно, проверять клиентскую подпись он будет по этим сообщениям. Подпись, присланную клиентом, перехватывающий узел передаёт без изменений. Так как сообщения различаются, подпись не сойдётся. Перехватывающему узлу не известен секретный ключ клиента, поэтому перехватывающий узел не может подписать за клиента сообщения сессии в сторону подлинного сервера. Если же сообщения прокси передавал без изменений, то это означает, что перехвата TLS не случилось, а случилось обычное TLS-соединение и прокси не сможет раскрыть трафик.
Важная оговорка: это всё верно, но лишь без учёта возможности принудительного понижения стойкости – в принципе, перехватывающий узел, активно вмешиваясь в соединение, может вынудить стороны TLS согласовать заведомо нестойкие ключи и параметры протокола. Это позволит расшифровать трафик в пассивном режиме. Однако это совсем другая схема перехвата, она гораздо сложнее, клиенты типа современного браузера лучше защищены от применения подобных атак, а в TLS давно есть дополнительные индикаторы, помогающие такую атаку обнаружить, и т.д. В общем, в записке речь идёт о максимально простой схеме перехвата – с полной подменой узла.
А что если у перехватывающего узла есть подходящий секретный ключ и дверенный клиентский сертификат? Тогда – да, перехватывающий узел сможет выдать себя за аутентифицированного клиента в сторону подлинного сервера и продолжить прозрачный перехват, просто пригнорировав аутентификационный ответ прослушиваемого клиента.
Тут есть тонкий момент: нельзя забывать, что в TLS проверить корректность подписи и валидность клиентского сертификата должен подлинный сервер. Если сервер реально использует результат аутентификации клиента, то сессия с MITM – развалится (если у перехватывающего прокси нет клиентского секретного ключа). Но это именно особенность TLS. То есть, сервер должен всё проверять, но может и не проверить. Если сервер реально не проверяет значение клиентской подписи, то перехватывающий прокси может прислать что угодно похожее на подпись и TLS-соединение продолжит работать как обычно. Ну и тем более так будет, если сервер вообще не использует клиентской аутентификации в TLS (обычное дело).
И это приводит к следующим особенностям трансляции доверия через TLS. Предположим, что есть дополнительный прикладной протокол аутентификации, работающий через TLS, но не использующий встроенную в TLS клиентскую аутентификацию. Простейший вариант: клиент вводит пароль. Понятно, что тут MITM-прокси просто пересылает запрос на пароль клиенту, а пароль от клиента – пересылает серверу. Всё прозрачно работает, прокси узанёт пароль.
Более сложный вариант: у клиента есть секретный ключ для цифровой подписи, сервер верит в открытый ключ, соответствующий этому секретному. Сервер присылает запрос на подпись некоторых данных – клиент подписывает – сервер проверяет и убеждается, что у клиента есть секретный ключ, если всё сошлось – клиент аутентифицирован. Помешает ли это MITM-прокси? Нет, не помешает. Прокси, в рамках штатного перехвата трафика, просто копирует запрос сервера, пересылает его клиенту, получает от клиента подпись, передаёт её серверу – сработало, сервер аутентифицировал клиента и незаметил вмешательство прокси. Почему это работает? Потому, что тут аутентификация не привязана к транспортной сессии: сервер проверяет, что запросы поступают от стороны, имеющей доступ к секретному ключу, парному к доверенному открытому, но не проверяет, что транспортная сессия установлена с той же самой стороной.
Что это всё означает? Вот что: представьте, что клиент авторизуется через тот или иной механизм, использующий цифровую подпись, выполняемую на стороне клиента; эта схема, с точки зрения простого MITM-перехвата TLS, не даёт дополнительной защиты сессии. То есть, всё происходит на пару уровней выше TLS: клиент что-то подписал, сервер выдал клиенту авторизационный токен, этот токен виден на стороне MITM-прокси, теперь сторона с прокси может выдать себя за аутентифицированного клиента, подпись не требуется. Если подпись потребуется, то прокси перенаправит запрос клиенту. Да, по сравнению с паролем, тут есть некоторое преимущество: секретный ключ подписи не утекает наружу. Но, с другой стороны, выгода в плане защиты информации не так уж велика: ведь MITM-прокси может попросить клиента подписать что угодно, прикинувшись подлинным TLS-сервером при помощи перехватывающего TLS-сертификата.
Комментировать »
Вот уже два с половиной месяца на 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).
Комментировать »
Сейчас веб-сайтах крупнейших российских банков в 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-серверов.
Комментировать »
Кстати, что касается обнаружения отзыва серверных 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.
Комментировать »
Недавно вышел документ 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) »
Наткнулся тут случайно на занятное решение в области внутреннего устройства LLM-системы Claude от Anthropic.
Я на днях попросил эту систему извлечь актуальный TLS-сертификат с некоторого веб-сервера (HTTPS, то есть). В ответ пришло подробнейшее объяснение того, что “песочница” на стороне Anthropic, которую данная система использует внутри, чтобы выполнять команды, перехватывает TLS, подставляя сертификат, сгенерированный TLS-прокси. “Песочница” тут – это контейнер или виртуальная машина, где исполняется системная среда, доступная “бэкенду” LLM. Сейчас все современные мощные системы этого типа максимально используют привычные программные среды и утилиты (Python, Bash, curl, OpenSSL и пр.), выдача утилит “подмешивается” в процесс подготовки ответа, и это даёт несравнимо лучший результат, чем простое “поточное генерирование” (банальный пример – арифметика: так как “привычный подход” приводит к смешным ошибкам, продвинутые системы ИИ-LLM уже давно считают числа при помощи скрипта на Python).
И вот, на стороне Claude, такая “песочница”, точнее – системное окружение “песочницы”, имеет технические ограничения, которые, тем не менее, “наблюдает” LLM. То есть, сразу отмечу, это ни какой-то там “побочный канал” – нет, Claude подробно расписывает, что, мол, такая вот ситуация обнаружилась, это “мешает мне напрямую получить сертификаты с сервера, поэтому буду искать обходные пути”. А потом начинает добывать сертификат другим способом. Что удивительно, делает это, условно говоря, успешно – таки сертификат (даже несколько сертификатов) был получен, но не непосредственно с исследуемого сервера (см. ниже), что, конечно, не соответствует задаче, так как сервер мог при этом возвращать что угодно другое.
Вообще, сказать с полной уверенностью, что выданное системой описание “песочницы” полностью соответствует действительности – довольно сложно: данная система достаточно быстро и уверенно генерирует детализированные объяснения на естественном языке почти что про что угодно. Так что, может, это специально так сделано. Однако выглядит всё весьма и весьма правдоподобно, поэтому примем, что так оно и есть.
Тем более, что вариант вполне логичный, и система даже прислала подменный сертификат, который возвращает в “песочницу” TLS-прокси: доменное имя, время начала действия (для прокси – время генерирования) сертификата – всё совпадает. То есть что там, на бэкенде, происходит: LLM генерирует шелл-скрипт, который, при помощи вызова утилиты s_client OpenSSL, должен подключиться к исследуемому по моему запросу серверу и вернуть (кроме прочего) серверный сертификат и дополнительные, промежуточные, сертификаты. В результате, сертификаты возвращаются, но это подменные сертификаты, которые сгенерированы прокси-сервером. Это в чистом виде то, что принято обозначать буквами MITM. В серверном сертификате указано имя того узла, к которому было обращение, но выпущен этот сертификат перехватывающим прокси (что нетрудно понять по именам удостоверяющих центров).
Зачем такой перехват может быть сделан? Чтобы отслеживать трафик внутренних систем, управляемых LLM – в трафике может быть что-то подозрительное. Можно было бы делать более тонкий перехват, но это очень сложно, а примитивный “тотальный MITM” – работает подобно молотку: не избирательно, зато просто и предсказуемо.
Похожая ситуация, когда кому-то, кто пытается проверить что-то про TLS и TLS-сертификаты, нахально мешает локальный антивирус – очень распространена. Даже на корпоративных системах профильных компаний. Антивирус перехватывает TLS-соединение в HTTPS, подставляет свой сертификат, сгенерированный под запрос, а реальный сертификат сервера – пользователь не может увидеть совсем. (Оно, конечно, должно бы быть понятно, что такой подход полностью уничтожает весь смысл TLS в вебе, особенно, если это применяется к браузеру на локальном рабочем месте, поскольку вся валидация отдаётся на откуп антивирусу, а специально подготовленный кривой ответ сервера – может сломать сразу локальный антивирус, исполняемый с максимальными правами, и даже не браузер, но это – другая история, и тут уж ничего не поделать, видимо.)
Схема, применяемая на бэкенде Anthropic, – согласно описанию, данному Claude, – несколько другая, но очень похожа: TLS-прокси подменяет всё подряд, и выдаёт сертификаты даже для заведомо несуществующих DNS-имён, под которыми нет никаких веб-узлов (имеется в виду имя в поле SNI). Насколько это оправданно? Опять же, сложно сказать. Зависит от целей. С одной стороны, это полностью искажает сетевую реальность и сводит к нулю ценность такой среды, в которой, тем не менее, LLM-система что-то запускает и пытается использовать результат, растрачивая немалые вычислительные ресурсы. С другой стороны, система вынуждена “искать обходные пути”, и успешно находит их, – это потом можно представить в газетах как “взлом”, обход “ограничений безопасности” и “выход из песочницы”.
Что же касается сертификатов, то, согласно описанию от Claude, они были получены из логов Certificate Transparency (при помощи ловкого обходного запроса к сервису ssllabs.com – чтобы получить отпечатки). Это совсем не то, что требовалось, но, в данном конкретном случае, оказалось даже несколько лучше (опять же, это вовсе не про “ИИ нашёл лучшее решение” – нет, ИИ-сервис, вынужденный бороться с “песочницей”, случайно достал из CT-логов то, что показалось занятным).
Комментарии (1) »
В продолжение прошлой записки про короткоживущие TLS-сертификаты на dxdt.blog: там было написано, что я перестал отзывать сертификаты для dxdt.blog – так вот, подумав ещё, я всё же добавил отзыв предыдущего сертификата, если успешно выпустился новый. Потому что пока что способ отозвать есть – почему бы его не использовать? Тем более, что это вполне себе обычная ситуация: новый сертификат заменяет старый, для этого даже есть код причины отзыва – Superseded (но см., однако, ниже). Другое дело, что в этих сертификатах для dxdt.blog сейчас одинаковый серверный ключ – это, как бы, переводит основной смысл отзыва в плоскость чистого эксперимента. Но тем не менее.
Let’s Encrypt сейчас предоставляет только один интерфейс для проверки статуса сертификата – списки отозванных сертификатов (CRL-файлы, адреса точек раздачи которых указаны в самом сертификате). От OCSP-респондера давно отказались (и совершенно правильно сделали: OCSP – так себе технология). Собственно, для “сверхкоротких” TLS-сертификатов сейчас вообще допускается отсутствие информации о статусе, то есть, можно и CRL не публиковать. Let’s Encrypt пока что публикуют.
Кстати, немного про устройство раздачи CRL у Let’s Encrypt. Список отозванных сертификатов (или просто “список отзыва”) – это, буквально, удостоверенный подписью список серийных номеров сертификатов, выпущенных данным Удовтоверяющим Центром (УЦ), которые отозваны (иногда – с указанием причины отзыва). Так как сертификатов Let’s Encrypt выпускает много (“много” – это мягко сказано), то можно ожидать, что и списки отозванных сертификатов будут быстро “пухнуть”.
На практике это не всегда так – сертификатов отзывается мало, потому что, вообще говоря, отзыв сертификата – не считается штатным событием. (Но, тем не менее, я таки стал отзывать каждый короткоживущий сертификат, до истечения его срока действия – но то больше в качестве эксперимента.) Всё же, чтобы, видимо, как-то подготовиться к потенциальному “распуханию” списков отзыва, Let’s Encrypt использует некий “шардинг” – CRL для одного УЦ нарезаны на несколько файлов (судя по всему, на 128): например, есть точка раздачи по адресу http://ye1.c.lencr.org/108.crl, а есть и http://ye1.c.lencr.org/18.crl, и 10.crl и т.д., думаю, схема именования ясна. Это всё CRL от УЦ YE1 (как видно и по имени хоста). Конкретный адрес, с разным “фрагментом” CRL, пишется в конкретный оконечный сертификат. Например, сейчас в сертификате на dxdt.blog указана точка http://ye2.c.lencr.org/103.crl.
Отзывать сертификат можно при помощи ACME – там есть специальный интерфейс. ACME вообще предлагает несколько способов отзыва. Понятно, что для отзыва – нужно как-то минимально подтвердить связь отзывающего аккаунта либо с сертификатом, либо с именем в сертификате. Иначе можно будет отзывать чужие сертификаты.
В ACME предусмотрено три основных способа такого “связывания”:
1) через ACME-аккаунт – то есть, запросить отзыв может тот же аккаунт, под которым отзываемый сертификат был получен от УЦ;
2) через секретный ключ от открытого, указанного в сертификате – то есть, любой аккаунт может отозвать сертификат, если запрос подписан секретным ключом от сертификата (это понятный и самый строгий механизм: если секретный ключ от сертификата скомпрометирован, то единственное, где подписи от этого ключа ещё можно доверять, это запрос на отзыв соответствующего сертификата);
3) через подтверждение права управления именем (DCV) – если ACME-аккаунт подтвердил, что управляет именем, указанным в сертификате, то этот аккаунт может отозвать любой сертификат, выпущенный УЦ для подтверждённого имени; тоже логичное решение – сторона, фактически управляющая доменом (или IP-адресом), должна иметь возможность отозвать “прошлые” или “старые” сертификаты.
Заметьте, кстати, что третий метод позволяет отозвать любой сертификат, где единственное подтверждённое имя указано в списке имён (то есть, можно отозвать сертификаты, в которых есть ещё какие-то другие имена/адреса в SAN).
Я сейчас отзываю “замещённые” сертификаты dxdt.blog просто тем же ACME-аккаунтом.
Комментировать »
ACME – это протокол автоматизации, применяемый для запроса и выпуска TLS-сертификатов. Нередко заходит речь о том, как этот протокол использовать правильно, чтобы получить какие-то выгоды в плане, что называется, архитектуры безопасности. Поделюсь некоторыми соображениями, в том числе, схемой. Возможно, это будет полезно, в том числе, в качестве образовательного материала.
Прежде всего, несколько базовых моментов. Естественно, на каких-то веб-ресурсах, типа “личный сайт”, можно использовать банальный механизм – тот или иной готовый ACME-клиент, который исполняется хоть бы прямо и на той же виртуальной машине, где и сам веб-сервер. Но для мало-мальски серьёзного сервиса – такое, конечно, является неграмотным решением и недопустимо: нельзя держать вместе с веб-сервером некоторое непонятное внешнее ПО, которое, потенциально, имеет права суперпользователя и может работать с серверными секретными ключами и сертификатами (насчёт ограничений прав пользователя: тут, конечно, нельзя забывать, что в большинстве современных ОС, – в том числе, серверных, – от “обычного” пользователя до суперпользователя – дорога весьма коротка и часто пряма; впрочем, это другая тема).
Итак: нельзя держать системное ПО внешнего предназначения, да ещё и связанное с криптографическими артефактами, там же, где работает защищаемый веб-сервер, и там же, где генерируются ключи. ACME этого не требует. Напротив – под ACME можно построить безопасную архитектуру с полной автоматизацией. Однако защищённая архитектура, с разделением ролей, получается сложнее (см. схему).
Ниже мы разберёмся с тем, как не только можно разделить процесс запроса TLS-сертификата и процесс использования TLS-сертификата, но ещё и вспомним, что секретный ключ, соответствующий сертификату, можно (и нужно) унести и с машины, на которой работает TLS-сервер (это не обязательно, но именно такой вариант рассматривается ниже).
Несколько важных тезисов.
ACME-клиенту нужен доступ только до ACME-сервиса выпускающего Удостоверяющего Центра (УЦ), больше никаких доступов не требуется. То есть, не требуется ни доступ к веб-серверу, ни доступ к DNS-серверу. Понятно, что размещать код подтверждения всё равно нужно, но это может делать другой компонент – ещё раз обратите внимание: роль ACME-клиента ограничивается взаимодействием с ACME-сервисом УЦ, такое взаимодействие – необходимо, а всё остальное, что сейчас привычно навешивают на единственный клиент, является опциональным. Навешивать опциональные фукнции на ACME-клиент, в случае серьёзного сервиса, – неграмотно.
Секретный серверный ключ TLS-сервера не требуется при выпуске сертификата – этот ключ не нужно передавать в УЦ, не нужно показывать его и ACME-клиенту. В схеме, которую мы рассмотрим ниже, секретные ключи вообще хранятся на отдельном подписывающем сервере, их нет даже на TLS-узлах, принимающих входящий трафик пользователей.
Валидация права управления именем (DCV), в защищённом распределённом сервере, должна происходить строго через DNS. Поэтому мы спроектируем отдельный набор “микросервисов”, реализующих такую проверку. Прохождение DCV в ACME требует специального префикса (или “суффикса”, тут как посмотреть): _acme-challenge. Это сделано специально, поскольку позволяет вынести проверку на отдельные DNS-серверы, которые не поддерживают основную зону. Размещение DNS-записей для DCV не требует передачи ACME-клиенту каких-то ключей доступа к авторитативным серверам DNS-зоны (далее они обозначаются – NS). Мы будем использовать самый верный вариант настройки DNS – делегирование ACME-имени _acme-challenge на отдельные NS (можно размещать запись непосредственно на NS основной зоны, можно настроить и CNAME, но этот последний вариант – не рекомендуется использовать). Никакая разумная конфигурация DNS для ACME-DCV не требует передачи ACME-клиенту контроля над зоной или каких-то ключей управления, всегда можно сделать безопасную схему.
Итак, архитектурное решение для реализации выпуска и использования TLS-сертификатов при помощи ACME-автоматизации. Решение состоит из трёх основных элементов: подсистема DNS – для обеспечения DCV; основной сервис TLS – это основные узлы сервиса, куда подключаются пользователи, можно считать, что за ними стоят защищаемые веб-серверы; диспетчер ACME – для взаимодействия с внешним УЦ, заказа и получения сертификатов.
Сама схема – ниже (по клику – в большем разрешении).
В качестве примера тут зона example.com. ACME-имя _acme-challenge.example.com – делегируется на два специализированных DNS-сервера, которые предназначены для публикации кодов подтверждения в TXT-записях. Данные на эти выделенные серверы передаёт специальный сервис, роль которого состоит в получении свежих данных DCV от диспетчера ACME и в передаче этих данных на публикацию. Почему изолированы NS? Потому что они не должны иметь доступ к основной зоне. При этом, в общем случае, перехват управления этими NS-ами позволяет заказывать и выпускать сертификаты через другой ACME-аккаунт, но только в том случае, если УЦ не поддерживает указания ACME-аккаунта в CAA-записи. Дело в том, что наши специализированные NS для DCV просто не позволяют публиковать CAA-записи (тем более – в зоне уровнем выше). Поэтому применяется CAA из основной зоны, а там, предположим, указан идентификатор аккаунта, которому только разрешено заказывать сертификаты для этого имени.
Блок сервисов, связанный непосредственно с TLS (слева вверху на схеме). Обратите внимание, что здесь все операции, использующие серверный секретный ключ “от сертификата”, вынесены на специальный подписывающий сервер. Речь про секретный ключ, соответствующий открытому ключу в сертификате сервера. Вообще, при установлении TLS-соединения сам этот долговременный секретный серверный ключ не требуется, требуется возможность подписывания сессии (значения хеш-функции). Понятно, что для вычисления подписи секретный ключ нужен, но само его значение никакой роли в TLS-соединении не имеет. А цифровая подпись, при установлении TLS-соединения, требуется всего один раз. (Тут речь строго про современную схему TLS 1.3, где использование RSA для передачи сессионного секрета прямо запрещено, и такой секрет должен вычисляться по протоколу Диффи-Хелмана.)
Поэтому операции подписи могут быть прозрачно вынесены на защищённый сервер, где будет доступ к секретному ключу. При такой схеме – веб-сервер не знает секрета от TLS-сертификата. Такой “бесключевой” TLS вполне возможен и используется в решениях с повышенными требованиями безопасности. (Но для ACME это не является обязательным, так что, в принципе, если наладить такой вариант не получается, поскольку он показался слишком сложным, то можно объединить управление ключами с веб-сервером.)
Блок TLS на схеме содержит “микросервис” под названием “Формирователь CSR”. CSR – это файл запроса на сертификат. Этот файл, помимо других параметров, содержит открытый ключ сервера для включения в сертификат и цифровую подпись от этого же ключа. Именно по причине наличия подписи наш формирователь CSR должен иметь доступ к подписывающему серверу: подготовив блок CSR, формирователь запрашивает подпись у этого сервера и присоединяет значение подписи к блоку CSR. Получившийся файл можно использовать в ACME-клиенте для запроса сертификата (после прохождения DCV – см. ниже). Обратите ещё раз внимание: секретного ключа “от сертификата” тут нет ни у формирователя CSR, ни у TLS-узлов – что уж говорить про ACME-клиент.
ACME-клиент в этой схеме взаимодействует только с ACME-сервисом УЦ, где, по команде от программы-диспетчера, исполняемой отдельно, запрашивает DCV и сертификаты. Как описано выше – коды подтверждения передаются через диспетчер на публикацию в контур DNS. При штатной работе, после того, как TXT-записи опубликованы, ACME-клиент запросит проверку на стороне УЦ и DNS-резолвер УЦ обратится к DNS, чтобы получить по независимому каналу значение кода DCV из TXT-записи – это соответствует оранжевой стрелке внизу схемы.
Посмотрим ещё раз на шаги алгоритма выпуска TLS-сертификата, при штатной работе.
***
1.
Диспетчер (см. схему) получает CSR с актуальными данными от формирователя CSR (подпись от защищённого сервера, с актуальным ключом, в CSR – нужное DNS-имя).
2.
Диспетчер отправляет в ACME-клиент запрос на DCV (CSR на этом шаге в ACME не требуется, но будет нужен позже).
2.1. ACME-клиент инициирует взаимодействие с УЦ через ACME-аккаунт (возможно, используя отдельное хранилище ключа от ACME-аккаунта – см. схему; зачем это может быть нужно – возможно, распишу в отдельной записке; главное – не забывайте, что ACME-аккаунт существует, там есть секретный ключ и он тоже важен).
2.2. ACME-клиент запрашивает прохождение DCV (проверка права управления DNS-именем) на стороне УЦ и получает код подтверждения, который требуется разместить в DNS.
2.3. ACME-клиент передаёт этот код подтверждения (DCV-код) диспетчеру, оджидает публикации кода в TXT-записи.
3.
Диспетчер формирует файлы данных с актуальным кодом подтверждения (DCV-код) и ожидает публикации (у диспетчера нет прямого доступа к сервису подготовки TXT-записей, напротив – тот сервис периодически сам проверяет статус диспетчера, определяет, не нужно ли разместить новые записи).
4.
Сервис подготовки TXT-записей забирает текущий код DCV из обменной области диспетчера.
5.
Сервис подготовки TXT-записей направляет команду публикации TXT-записей авториативным серверам специализированной зоны _acme-challenge и получает подтверждение публикации.
6.
Если публикация TXT прошла успешно, сервис подготовки TXT-записей направлет подтверждение диспетчеру.
7.
Диспетчер отправляет команду фактического запуска DCV ACME-клиенту и ожидает получения сертификата (если проверка пройдёт успешно).
8.
ACME-клиент запрашивает фактическую проверку DCV у УЦ (через ACME-API) и начинает периодический опрос статуса заказа на стороне УЦ (ожидание выпуска сертификата – это свойство ACME).
9.
Если DCV завершилась корректно и успешно, то ACME-клиент получает от диспетчера CSR и запрашивает новый сертификат для подтверждённого имени (или для нескольких имён). Обратите внимание: обычно, у ACME УЦ есть некоторый период, в течение которого действует пройденная DCV. Это означает, что запросить новый сертификат можно без DCV, если срок валидности прошлой успешной проверки для этих же имён не закончился. В описании и на схеме этот момент не учитывается – он не имеет принципиального значения.
10.
Если сертификат успешно выпущен, то ACME-клиент скачивает его и возвращает диспетчеру. Диспетчер подготавливает полный набор промежуточных сертификатов, нужный для успешного использования. Промежуточные сертификаты либо можно получить через ACME-клиент, если УЦ это поддерживает, либо скачать по ссылкам в оконечном, серверном сертификате (этот последний метод – гораздо надёжнее). Диспетчер валидирует цепочку сертификатов, перед тем как передать её дальше.
11.
Диспетчер размещает новый сертификат и цепочку промежуточных в обменной области, откуда их могут забрать либо сами TLS-узлы, либо промежуточный узел, реализующий “деплой” сертификатов. Вариант с таким промежуточным узлом на схеме не показан (тем не менее, я бы сказал, что это предпочтительный вариант).
12.
TLS-узлы забирают новый сертификат из обменной области диспетчера и устанавливают его на TLS-сервер (с дополнительной проверкой валидности по цепочке). Обратите внимание, что секретный ключ уже настроен на стороне подписывающего сервера – TLS-узлам лишь нужно переключиться на новый идентификатор ключа, который они используют при запросе подписи. Секретный ключ уже настроен потому, что он необходим для получения подписи на CSR.
13.
Переход на новый сертификат завершился.
***
Управление расписанием получения новых сертификатов, график замены ключей – остаются за пределами данного описания. Так же, как и процесс отзыва сертификата (возможно, напишу отдельно). Не забывайте, что в ACME не существует таких функций как “перевыпуск” или “продление” TLS-сертификата – это довольно частая терминологическая ошибка. ACME подразумевает, что клиенты всегда обращаются за новым сертификатом.
Комментировать »
Отозванный TLS-сертификат и “недоверенный” TLS-сертификат – две принципиально разных ситуации. Под “недоверенным” здесь подразумевается TLS-сертификат, для которого не удалось установить доверие – например, сертификат подписан от ключа, который не считается доверенным проверяющей стороной, или сертификат самоподписанный (при этом, опять же, нет доверия ключу). В случае с браузером и веб-сайтом – на веб-сервере установлен серверный сертификат, выпущенный Удостоверяющим Центром (УЦ), который не входит в набор доверенных УЦ браузера.
Для таких недоверенных сертификатов невозможно проверить статус – отозван или нет. Почему? Потому что проверка статуса требует доверия источнику информации об этом статусе. Обычно, адрес, по которому можно получить ответ о статусе, записан в самом сертификате (точка раздачи CRL или OCSP-респондер). Соответственно, если проверяющая сторона не доверяет подписи на сертификате, то она не доверяет и составу сертификата, и, что важнее, УЦ, который сертификат выпустил. Но самое главное, что, очевидно, просто нет смысла проверять статус сертификата, которому, по другим причинам, нет доверия и так. Отозван или нет – без разницы.
Совсем другая история – достоверно отозванный сертификат. Сам факт того, что проверяющей стороне удалось определить статус сертификата (отозван), означает, что эта сторона смогла построить доверенную цепочку до УЦ, а потом, используя эту цепочку, проверила статус. То есть, всякий ответ о статусе сертификата обязательно должен быть удостоверен УЦ – иначе нет смысла. УЦ подписываются и OCSP-ответы, и CRL. Естественно, недоверенный сертификат тоже может быть “отозванным”, формально, но информация о его статусе не может являться доверенной, так что – она не имеет значения, не влияет на фактический статус сертификата.
Пример для отозванного TLS-сертификата: браузер подключился к веб-узлу, получил серверный сертификат, смог его валидировать успешно, но, на последнем шаге, получил доверенный ответ от УЦ, что сертификат отозван. Это означает, что сертификат заведомо плохой – об этом есть подтверждённая информация от УЦ. Почувствуйте, как говорится, разницу: отозванный сертификат – отозван доверенным способом, проверка подтверждает, что браузеру удалось установить цепочку доверия УЦ; недоверенный сертификат – про него ничего нельзя сказать, он может быть произвольным по составу и статусу, а доверия УЦ установить не удалось.
Именно поэтому должно существенно различаться поведение стороны, которая валидирует сертификат, например, TLS-клинета: для отозванного сертификата – запрещаем доступ к ресурсу; для недоверенного – предоставляем пользователю возможность выбрать, что делать (например, “всё равно продолжить” в браузере), предварительно сообщив, что подлинность определить невозможно, так что пользователь сам должен решить вопрос с доверием.
Комментировать »

Новый