Апокриф 12

Инфраструктура открытых ключей: цепочки, имена, отзыв

Инфраструктура открытых ключей: цепочки, имена, отзыв

PKI — это попытка ответить на вопрос «чья это подпись» без личных встреч. Ответ держится на доверии к удостоверяющим центрам, а доверие — на правилах, которые каждый обязан проверять одинаково. Вся история атак на PKI — это история мест, где правила не проверялись или проверялись не полностью.

Тема разбирает сертификат X.509 изнутри: поля, расширения, подпись. Затем построение и проверку цепочки: кто кому доверяет, как работают ограничения, что такое path length и name constraints. Дальше — сопоставление имени: SAN против CN, подстановочные знаки и типичные обходы. Потом отзыв: CRL, OCSP, stapling и Certificate Transparency. Завершается разбором инцидентов: DigiNotar, Comodo, Superfish — и выводом, что PKI ломается не криптографией, а процессом.

Сертификат X.509

Поля и назначение

Сертификат связывает открытый ключ с именем: субъект, издатель, серийный номер, срок действия, открытый ключ, расширения и подпись издателя. Подпись вычисляется по DER-кодировке tbsCertificate — той части, которая содержит все поля, кроме самой подписи 1.

Расширения определяют, что сертификату разрешено: basicConstraints (является ли он CA, ограничение глубины), keyUsage (подпись, шифрование, только сертификаты), extendedKeyUsage (TLS-сервер, TLS-клиент, код), subjectAltName (имена, для которых он действителен), nameConstraints (какие имена может выдавать этот CA).

Доверие

Корневые сертификаты находятся в хранилище доверия операционной системы или браузера. Цепочка: лист → промежуточный → корень. Проверяющий строит путь до доверенного корня и проверяет подписи, сроки, расширения и ограничения.

Ключевая идея: доверие не «вычисляется», оно «назначено». Выдача сертификатов всё чаще автоматизируется по ACME 8, и это меняет профиль риска: скорость выдачи растёт, а проверка домена становится программной. Браузер доверяет корню, потому что его туда добавили; вся стойкость PKI сводится к тому, насколько аккуратно этот список ведётся.

Проверка цепочки

Что проверяется

Проверка цепочки (RFC 5280, раздел 6) включает: подпись каждого сертификата ключом издателя, срок действия на текущий момент, соответствие basicConstraints (промежуточный обязан быть CA), ограничение глубины pathLenConstraint, корректность keyUsage и extendedKeyUsage, ограничения имён nameConstraints, а также проверку отзыва — но её объём зависит от политики клиента, и ниже это оговорено отдельно.

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

Пропуск любого пункта проверки — уязвимость. Классический пример: проверка подписи без проверки basicConstraints позволяет подписать сертификат ключом, который не является CA.

Ограничения имён

nameConstraints в корневом или промежуточном сертификате говорит, какие домены он вправе обслуживать. Это защита от «слишком широкого» промежуточного CA: если он скомпрометирован, противник не сможет выписать сертификат на чужой домен. Проверка nameConstraints обязательна и часто забывается в самописных проверках 2.

Схема цепочки и ограничений на рисунке 1.

Цепочка сертификатов
Рисунок 1. Лист → промежуточный → корень: на каждом шаге проверяются подпись, срок, назначение и ограничения

Сопоставление имени

SAN против CN

Современное правило: имя берётся из subjectAltName, поле commonName для этого не используется 3. Исторические реализации проверяли CN, что давало обходы: сертификат с CN=example.com и SAN на другой домен принимался по CN.

Подстановочные знаки

*.example.com соответствует a.example.com, но не a.b.example.com и не example.com. Ошибки в сопоставлении (принятие *.example.com за example.com.evil.com, или наоборот) — классика обходов. Правило: подстановка заменяет ровно одну метку слева и не может быть частью публичного суффикса.

Null-байты, юникод-гомоглифы, завершающие точки, регистр — всё это места, где строгий парсер обязан нормализовать имя до сравнения. Схема на рисунке 2.

Сопоставление имени
Рисунок 2. Имя берётся из SAN; подстановка покрывает одну метку слева, нормализация обязательна

Отзыв

CRL и OCSP

CRL — подписанный список отозванных серийных номеров, обновляется периодически. OCSP — запрос по конкретному сертификату, ответ подписан; формат запроса и ответа описан в RFC 6960 4. Проблемы: CRL бывают огромными и устаревшими, OCSP создаёт зависимость от доступности службы и утечку приватности (запрос раскрывает, какие сайты посещает клиент).

Stapling и мягкий отказ

OCSP stapling позволяет серверу приносить подписанный ответ OCSP с собой, не раскрывая клиента. Мягкий отказ (soft-fail) — принимать сертификат, если проверить отзыв не удалось — на практике превращает отзыв в формальность: противник блокирует OCSP и проходит.

Отзыв как политика, а не как безусловное требование

Обязательность проверки отзыва зависит от клиента и сценария. Браузеры и публичные клиенты обычно применяют мягкий отказ: недоступность OCSP не блокирует соединение, иначе сбой одной службы останавливал бы половину интернета. Клиенты с жёсткой политикой (корпоративные, финансовые, часть библиотек с -crl_check) применяют жёсткий отказ и отвергают сертификат при любой неопределённости. Есть и промежуточные режимы: проверять только при наличии stapled-ответа, игнорировать CRL, ограничивать проверку списком известных издателей.

Практический вывод: «проверка отзыва обязательна» — не универсальное утверждение о X.509, а выбор политики. Уязвимость возникает не от отсутствия проверки самой по себе, а от расхождения между заявленной политикой и фактическим поведением кода; при мягком отказе противнику достаточно заблокировать канал к OCSP, при жёстком — достаточно недоступности службы, чтобы устроить отказ в обслуживании. Проектировщик выбирает, какой из этих рисков ему дороже.

Certificate Transparency

CT публикует все выданные сертификаты в журналы, построенные на деревьях Меркле (апокриф 7). Клиент проверяет наличие SCT (подписанной метки времени) и может обнаружить сертификат, выданный на его домен без его ведома 5. CT не предотвращает выдачу, но делает её обнаруживаемой — это сдвиг от предотвращения к прозрачности.

Механика доверия к журналу опирается на три проверяемых объекта. Signed Certificate Timestamp (SCT) — обещание журнала включить сертификат; подписан и содержит время. Proof of inclusion — доказательство, что конкретная запись находится в дереве с данным корнем: путь из хешей от листа к корню, проверяемый за логарифмическое число шагов. Proof of consistency — доказательство, что новая версия дерева продолжает старую и ничего из неё не удалено: без него журнал мог бы «переписать» историю, выдав новый корень на месте старого. Проверка включения без проверки согласованности оставляет ровно ту атаку, от которой CT защищает, поэтому в мониторинге нужны обе.

Инциденты

DigiNotar

В 2011 году голландский CA DigiNotar был скомпрометирован, и противник выдал сотни сертификатов, включая *.google.com. Браузеры отозвали доверие к корню, компания обанкротилась. Урок: компрометация CA — компрометация всего, что он подписал, а обнаружение зависит от внешнего мониторинга 6.

Comodo и Superfish

Comodo (2011) — поддельные сертификаты через взлом реселлера. Superfish (2015) — предустановленный корневой сертификат с известным закрытым ключом, который позволял перехватывать TLS на ноутбуках. Урок: доверие к корню — это доверие ко всему, что этот корень может подписать, включая скомпрометированный закрытый ключ.

Что общего

Все три случая — не взлом криптографии, а слабость процесса: контроль доступа к ключам, проверка выдачи, аудит хранилищ доверия. Массовые измерения перехвата TLS показывают, что подменённые корни встречаются в корпоративных и домашних сетях регулярно 7.

Вывод: PKI — организационная конструкция, и её надо оценивать как процесс.

Итоги темы

  • Сертификат связывает ключ с именем; доверие назначается хранилищем.
  • Проверка цепочки включает подписи, сроки, назначение и ограничения имён.
  • Имя берётся из SAN; подстановка покрывает одну метку; нормализация обязательна.
  • Отзыв работает только при жёстком отказе; CT делает выдачу обнаруживаемой.
  • Инциденты PKI — про процесс, а не про математику.

Литература

  1. RFC 5280: Internet X.509 Public Key Infrastructure — Certificate and CRL Profile. 2008. — структура сертификата и алгоритм проверки цепочки.
  2. RFC 6125: Representation and Verification of Domain-Based Application Service Identity. 2011. — правила сопоставления имён, SAN и подстановочные знаки.
  3. CA/Browser Forum Baseline Requirements. — требования к выдаче сертификатов и проверке доменов.
  4. RFC 6960: Online Certificate Status Protocol. 2013. — OCSP и его ограничения.
  5. RFC 6962: Certificate Transparency. 2013. — журналы, SCT и деревья Меркле.
  6. Wilson R. How DigiNotar Was Hacked. 2012. — разбор инцидента и его последствий.
  7. Durumeric Z. et al. The Security Impact of HTTPS Interception. NDSS 2017. — массовое измерение перехвата TLS.
  8. RFC 8555: Automatic Certificate Management Environment (ACME). 2019. — автоматизация выдачи и её риски.