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

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

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

Введение

Электронный сертификат — это цифровой документ, выполняющий ряд задач:

  1. Определить некоторый субъект и подтвердить его физическое/юридическое существование. В зависимости от уровня валидации требования к верификации субъекта могут быть разной строгости.

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

  3. Определить назначение этой пары ключей, например использование в TLS, подпись других сертификатов, верификация списка отозванных сертификатов и т.д.. Помимо этого определяется и более уточняющее применение, такое как подпись исполняемого кода, аутентификация TLS сервера/клиента, защита email и пр..

  4. Предоставить дополнительную информацию, необходимую для проверки сертификата и использования ключей из него, включая информацию о выдавшем ("заверившем") сертификат центре, его цифровую подпись, список криптографических алгоритмов, используемых для создания этой подписи, срок действия сертификата и прочие вспомогательные сведения.

Именно в этих четырёх пунктах описана ключевая функция электронных сертификатов, сжав их в одно определение мы можем сказать, что электронный сертификат подтверждает принадлежность некоторому субъекту пары ключей и определяет назначение этой пары.

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

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

О термине "шифровать"

Хочу отметить, что здесь и далее по тексту употребление термина "шифрование" в контексте цифровой подписи будет означать применение к данным асинхронного криптографического алгоритма с применением двух ключей (ключ - последовательность байт), где приватный ключ используется для "зашифровывания" данных, а соответствующий ему публичный ключ - их "расшифровывает". Если в результате расшифровки полученные данные (являющиеся по сути хэш-суммой, расчитанной подписавшим) совпали с самостоятельно расчитанной проверяющим суммой - это свидетельствует о владении автором подписи соответствующим публичному приватным ключом, а значит и сертификатом, где находится этот публичный ключ. И несмотря на то, что термин шифрование на деле обозначает сокрытие данных от третьих лиц с целью сохранения их секретности, а не аутентификацию субъекта, в данном контексте мне попросту удобно его употребление.

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

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

Почему проверяющий доверяет удостоверяющему ценру мы рассмотрим в описании сертификатов удостоверяющих центров, но если вкратце - сертификаты центров выдаются и подписываются другими, вышестоящими удостоверяющими ценрами, тем самым формируя так называемую цепочку доверия (chain of trust). В начале (в корне) этой цепочки находятся корневые центры (root CA), которым принадлежат самоподписанные (то есть выданные сами себе) корневые сертификаты (root certificate), эти сертификаты именуются "якорями доверия" ("trust anchor"), т.е. считаются авторитетными по-умолчанию и предустанавливаются в специальные локальные хранилища сертификатов операционных систем и браузеров. Поэтому, чтобы считаться доверенным, сертификату нужно вести своё "происхождение" от предустановленного корневого сертификата, либо корневого сертификата, установленного пользователем вручную.

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

Наиболее распространённым и единственным рассмариваемым в данном материале стандартом сертификатов является X.509. X.509 это международный стандарт, определяющий формат и методику создания, проверки и управления цифровыми сертификатами, используемыми в инфраструктуре открытых ключей (Public Key Infrastructure, PKI).
Инфраструктурой открытых ключей (PKI) называют набор правил, политик, служб, программного обеспечения и технических средств для обмена, использования, хранения и отзыва электронных сертификатов. Иными словами, это абстрактное обозначение системы, в рамках которой сертификаты выдаются, проверяются, отзываются, отслеживаются и т.д., причём PKI может быть как глобальной, благодаря которой, например, функционирует современный WWW, так и локальной, скажем внутренней корпоративной инфраструктурой компании.

Я не буду включать исторические справки о том, когда X.509 появился и как развивался, поскольку если убрать конкретные имена и даты - история развития стандарта не отличается от истории развития любой технологии, касающейся сетевого стека.
Упомяну лишь, что было придумано 2 подхода реализации сертификации: в первом доверие к сертификату обеспечивалось некоторой третьей стороной, уполномоченной крупной организацией, для которой репутационные риски превышали бы любую выгоду от злоумышленных действий, таким образом узел А доверяет узлу Б, если его сертификат был выпущен авторитетным издателем, то есть удостоверяющим центром.
Во втором подходе же сертификация основывалась на построении "сети доверия", где нет централизованных удостоверяющих центров, а вместо участники сети подписывают сертификаты друг друга, то есть если узел А доверяет узлу Б, то он доверяет любому сертификату, подписанному узлом Б.
По первому пути пошёл X.509, благодаря которому мы имеем сегодняшний глобальный WWW, подписываем электронные документы, спокойно устанавливаем ПО, разработанное людьми, которых мы никогда не встретим вживую. Второй подход реализован в сертификации в рамках стандарта PGP (OpenPGP), применяемого в более нишевых технологиях.

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

Структурно X.509 сертификат состоит из следующих полей (к сожалению Habr Markdown не умеет в переносы строк внутри полей таблицы, поэтому для удобства читателя я переформатировал таблицу в список):

  • Version
    Версия сертификата. Возможные значения: 1 (v1), 2 (v2), 3 (v3). Версия 3 является самой распространённой на данный момент, кроме того она поддерживает важные в контексте современных PKI поля-расширения (Extensions).

  • Serial Number
    Уникальный серийный номер, присвоенный удостоверяющим центром (CA). Используется для отслеживания, не был ли сертификат отозван.

  • Signature Algorithm
    Указывает алгоритм, используемый для хэширования, а также алгоритм для подписи сертификата CA. Помимо идентификатора алгоритма, может включать необходимые для работы алгоритма аргументы.

  • Subject
    Информация о субъекта, которому выдан сертификат. Представлена в структуре данных Distinguished Name (DN).
    Рассмотрим поля этой структуры:

    • C (Country) — страна

    • ST (State or Province) — штат или область

    • L (Locality) — город

    • O (Organization) — организация

    • OU (Organizational Unit) — подразделение

    • CN (Common Name) — общее имя субъекта сертификата. Например, для TLS‑сертификатов здесь обычно указано доменное имя, на которое выдан сертификат, а для code signing сертификатов указано имя организации‑издателя программы.

  • Issuer
    Информация об удостоверяющем центре, выдавшем сертификат. Представлена также в формате Distinguished Name (DN), однако в этом случае она описывает местонахождение и имя выдавшего центра.

  • Validity
    Период действия сертификата, состоящий из двух дат:

    • Not Before: дата начала действия сертификата.

    • Not After: дата окончания действия сертификата.

  • Subject Public Key Info
    Информация о публичном ключе субъекта:

    • Public Key Algorithm: алгоритм публичного ключа (например, RSA, ECDSA).

    • Subject Public Key: собственно, публичный ключ.

  • Issuer Unique Identifier
    Уникальный идентификатор выдавшего центра (CA). Опциональное поле, введённое в версии сертификата 2, на случай когда Issuer у нескольких сертификатов окажется одинаковым, на практике редко включается.

  • Subject Unique Identifier
    Уникальный идентификатор субъекта. Опциональное поле, введённое в версии сертификата 2, на случай когда Subject у нескольких сертификатов окажется одинаковым, на практике редко включается.

  • Extensions
    Расширения, введённые в версии 3. Позволяют добавлять дополнительные данные, такие как:

    • Basic Constraints: указывает, может ли этот сертификат подписывать другие сертификаты или является конечным в цепочке, иными словами является ли данный сертификат CA-сертификатом, или же "пользовательским" (например, TLS-сертификатом). Также включает целочисленное поле для ограничения длины цепочки доверия (центр A выдал центру B, центр B центру C, центр C центру D, длина цепочки - 4. Но если здесь указано 3 - сертификат не может считаться действительным).

    • Key Usage: битовые флаги, определяющие обобщённое применение ключей. А именно: цифровая подпись (общего характера), шифрование других ключей (для последующей транспортировки), шифрование произвольных данных, обмен ключами (например во время работы алгоритма Диффи-Хеллмана в TLS рукопожатии до версии TLS 1.3, для обеспечения безопасного обмена параметрами алгоритма используются ключи из сертификата сервера), подпись других сертификатов, подпись списка отозванных сертификатов (Certificate Revocation List, CRL), создания неотказной подписи (довольно специфическое применение, используемое в электронном документообороте, где подпись, заверенная подобным сертификатом, утверждает что субъект действительно сам подписал документ и не может юридически отказаться от неё), а также два прочих значения, указывающих используется ли публичный ключ только для ЗАшифровки или только для РАСшифровки, что применяется в комбинации со значением "обмен ключами", где, например, публичный ключ TLS-сервера используется клиентом чтобы ЗАшифровать данные, РАСшифровать которые сможет только сервер своим приватным ключом (хотя в случае цифровой подписи, о которой мы говорили всё время до этого - публичный ключ применялся для РАСшифровки с последующей проверки содержимого. Это еще раз показывает, что семантика пары ключей определяется сертификатом).

    • Extended Key Usage: указывает уточнённое назначение ключа (если таковое имеет место быть). Сюда входят: аутентификация TLS сервера/клиента, подпись исполняемого кода, защита email-сообщений, привязка достоверной временной метки к данным и подпись OSCP-ответов, содержащих информацию о том, был ли запрашиваемый сертификат отозван.

    • Subject Alternative Names: альтернативные имена субъекта. Наиболее распространённый пример это дополнительные доменные имена субъекта. Также здесь могут быть адреса электронной почты, URLы, IP адреса, всё зависит от контекста сертификата.

    • Name Constraints: ограничивает допустимые имена субъектов, которые может подписывать CA, например, определённые домены или IP‑адреса.

    • Certificate Policies: указывает политики сертификации, применимые к сертификату, и, при необходимости, ссылки на документы с описанием политики. Политика сертификации — это набор правил, указывающих на применимость сертификата к определённому сообществу и/или классу приложений с общими требованиями безопасности. Например здесь может быть номер политики и ссылка на некоторый PDF-документ или текстовое предписание о каких то ограничениях, связанных с сертификатом ("Valid for Microsoft Authenticode only").

    • Policy Constraints: устанавливает ограничения на политику сертификации в цепочке сертификатов, например, требует наличие определённых политик в промежуточных сертификатах.

    • CRL Distribution Points: список URL, по которым можно загрузить файл, содержащий Certificate Revocation List (CRL — списки отозванных сертификатов).

    • Freshest CRL: указывает местоположение самой свежей CRL‑записи, также известной как Delta CRL.

    • Authority Information Access (AIA): содержит ссылку для загрузки сертификата центра сертификации, выдавшего данный, а также URL, на который можно отправить OCSP‑запрос, для проверки, не является ли текущий сертификат отозванным.

    • Authority Key Identifier: хэш публичного ключа центра сертификации, который выпустил этот сертификат.

    • Subject Key Identifier: хэш публичного ключа данного сертификата.

    • И некоторые другие.

  • Signature
    Содержимое сертификата хэшировано (используя алгоритм хэш‑суммы из поля Signature Algorithm), а затем хэш подписан, т.е. зашифрован приватным ключом центра‑издателя сертификата (используя алгоритм шифрования, указанный в упомянутом поле). Полученная подпись может быть расшифрована публичным ключом издателя и сверена с хэш‑суммой проверяющего (например, веб‑браузера), тем самым подтверждая подлинность и неизменность сертификата.

Взглянуть на поля сертификата можно при посещении любой веб-страницы, нажав на иконку параметров (или знаменитый замочек, там где он остался) слева от URL адреса и выбрав информации о защищённости подключения, здесь разве что хочу порекомендовать просмотр сертификатов через Firefox, т.к. тот же Chrome урезает часть полей сертификата, делая его более удобочитаемым, но менее информативным. Здесь хочу отметить еще одну стороннюю, но интересную особенность Firefox: большинство популярных браузеров используют хранилище сертификатов ОС, однако у Firefox есть своё, собственное, где перечислены доверенные корневые сертификаты.
Для просмотра сертификатов подписи кода на ПК с Windows вы также можете нажать ПКМ по любому .exe файлу и перейти в "Свойства->Цифровые подписи", где можно выбрать интересующую вас подпись (обычно она там одна) и в "Сведениях" просмотреть её сертификат. На Linux для просмотра можно использовать утилиту openssl.

Хочу также отметить поле, именуемое Fingerprints/Thumbprint, которое можно увидеть при просмотре сертификата в некоторых средствах просмотра. Это поле представляет собой хэш-сумму всех полей сертификата и на самом деле не является частью X.509 сертификата, а расчитывается и отображается самим браузером. Подобный цифровой отпечаток используется для внутренней логики, например для идентификации / быстрого поиска сертификата в хранилище, "прикреплении" ("pinning") отпечатка сертификата к определённому вебсайту (чтобы при подключении браузер валидировал только сертификаты с такой же хэш-суммой), а также, поскольку отпечаток отображается в браузере вместе с полями сертификата - он может быть использован для ручной сверки хэш-суммы отпечатка и заранее отдельно расчитанной хэш-суммы того же сертификата.

Виды сертификатов

Цифровые сертификаты можно разделить на виды по нескольким категориям, в зависимости от контекста их применения, уровня валидации, подписи. Обращу внимание, что между собой эти категории никак не связаны, например TLS-сертификат (по применению), может обладать любым из описанных далее уровней валидации.
Также хочу отметить, что отличия между сертификатами внутри категорий выражаются в значениях их полей, особенно это касается рассмотренных ранее полей Key Usage/Extended Key Usage, а также, иногда, в сопутствующих процессах вроде выдачи, проверки и хранения.

По виду подписи

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

  • Сертификаты, подписанные центром сертификации (CA-signed certificates) - эти сертификаты выдаются и подписываются удостоверяющими центрами, таким образом в иерархии сертификатов всегда будет присутствовать вышестоящий промежуточный или корневой CA-сертификат. Браузеры и операционные системы, как правило, автоматически доверяют таким сертификатам, если сертификат корневого центра (от которого в иерархии происходит проверяемый сертификат) присутствует в их хранилищах доверенных сертификатов.

  • Самоподписанные сертификаты (Self-signed certificates) - это сертификаты, в которых субъект и издатель совпадают (т.е. в полях Subject и Issuer находится одна и та же сущность), а аутентифицирующая его цифровая подпись создаётся с использованием собственного закрытого ключа. Доверие к таким сертификатам является доверием напрямую к выпустившему сертификат.

    Один из важнейших видов самоподписанных сертификатов это глобальные корневые сертификаты, выпускаемые официально доверенными корневыми центрами сертификации. После выпуска, такой сертификат будет устанавливаться и обновляться в хранилище сертификатов вместе с официальными обновлениями ОС/браузеров, он будет использован как фундамент для дальнейшего подписания промежуточных сертификатов и построения цепочки доверия в глобальной PKI.
    Конечно, самоподписанный корневой сертификат также может быть и локальным для какой-либо среды, однако доверие к такому сертификату будет сохраняться только в пределах этой среды, например компании используют внутренние центры сертификации для выпуска "корпоративного" корневого сертификата и дальнейшего подписания им промежуточных, которые, например, выдаются другим организациям-клиентам для получения доступа к Business-to-Business API.

    В качестве прочих примеров самоподписанных сертификатов можно упомянуть: выпуск Windows самоподписанного сертификата для пользователя ПК чтобы шифровать/дешифровать файлы ОС, выпуск самоподписанного TLS-сертификата для отладки веб-приложений и сайтов разработчиками, аналогично - выпуск самоподписанного сертификата для создания подписи кода во время отладки исполняемого приложения и так далее. Доверие к этим сертификатам также ограничено средой их выпуска или средой, где сертификат был вручную установлен в хранилище сертификатов как доверенный.

По области применения

Сертификаты из разных областей применения служат разным целям, а значит будут отличаться по внутренней структуре (значению полей X.509), требованиям к безопасности (какие уровени валидации, криптографические алгоритмы допустимы) и другим параметрам.

И, несмотря на разнообразие сертификатов, если абстрагироваться, глобальных применений у сертификатов два:

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

  • Во-вторых, установка защищённого канала связи. Здесь можно упомянуть алгоритмы вроде RSA, используемые в ранних версиях TLS / внутренних самописных протоколах, где публичный ключ в сертификате используется для шифрования сообщения (в случае TLS для шифрования процесса обмена ключами, в ходе которого генерируются уже синхронные сессионные ключи), а его расшифровка возможна лишь держателем приватного ключа, таким образом, пара ключей из сертификата обеспечивает безопасный обмен параметрами соединения, а сам сертификат гарантирует, что сообщение может быть безопасно доставлено через публичные сети, после чего оно может быть расшифровано только при наличии у владельца сертификата приватного ключа.

    С версии TLS 1.3

    Даже если речь идёт о TLS 1.3, где публичный ключ из сертификата веб-сервера более не используется в процессе обмена ключами, ввиду применения только алгоритмов, обеспечивающих прямую совершенную секретность (PFS), здесь электронный сертификат сервера все еще применяется: начиная с 1.3 сервер помимо сертификата отправляет сообщение CertificateVerify с цифровой подписью, включающей хэш-сумму всех отправленных ранее TLS-сообщений, подписанную приватным ключом сервера, используя который, клиент может расшифровать подпись и также убедиться в принадлежности приватного ключа (а значит и сертификата с соответствующим ему публичным ключом) серверу. Это позволяет убедиться в личности сервера и предотвратить атаки вроде подмены DNS. Аналогичную проверку цифровой подписью проходит клиент, в случаях, когда сервер явно запрашивает у него аутентификацию.

Рассмотрим подробнее наиболее распространённые примеры использования сертификатов:

  • TLS (в прошлом SSL) сертификаты - протокол TLS обеспечивает установку защищённого канала связи между клиентом и сервером. Это достигается в том числе аутентификацией одной стороны другой, например, в классическом HTTPS-соединении клиент при подключении к серверу запрашивает его сертификат, чтобы убедиться, что подключение идёт к владельцу домена, основное доменное имя которого указано в поле сертификата Subject.CommonName (кроме этого альтернативные доменные имена и поддомены могут быть указаны в Subject Alternative Names), при этом доменное имя соответствует публичному не-зарезервированному адресу, сертификат актуален и подписан авторитетной организацией. Иными словами можно сказать, что TLS-сертификат позволяет любому клиенту, взаимодействующем с веб-сервером считать, что он взаимодействует с владельцем сертификата.

    Кроме доменного имени в Subject.CN, данный вид сертификатов отличают также поля Key Usage где указаны значения digitalSignature, keyAgreement, поле расширения Extended Key Usage, где для сертификата сервера указано значение serverAuth.

    Как упоминалось ранее, отдельные серверные программы, использующие TLS, могут включить проверку сертификата клиента, хотя аутентификация на прикладном уровне разумеется намного распространённее и проще для конечного пользователя. Такой сертификат отличает поле Extended Key Usage, где указан идентификатор значения clientAuth, а пара ключей из сертификата используется для создания электронной подписи, которая содержит подписанную хэш-сумму отправленных ранее TLS-сообщений и может быть проверена сервером используя публичный ключ из сертификата клиента. С версии TLS 1.3 аналогичную проверку проходит и сервер.

Wildcard-домены

TLS сертификат также может быть Wildcard ("универсальным"), в таком случае вместо домена (поддомена) указывается wildcard-домен, то есть символ астериск (`*`), который заменяется на любое поддоменное имя. Например сертификат, содержащий *любые* поддомены `example.com`, будет содержать wildcard-домен вида `*.example.com` в полях `Subject.CommonName` и/или `Subject Alternative Names`, таким образом покрывая домены вида `payment.example.com`/`commerce.example.com`/`login.example.com` и др, что позволяет масштабировать сервисы без нужды в выдаче сертификата под каждый новый поддомен.

Однако у таких сертификатов есть ограничения: во-первых он может покрывать только поддомены первого уровня, то есть в нашем примере выше сертификат НЕ будет включать в себя домены по типу `security.login.example.com` или `purchase.payment.example.com`. Во-вторых - wildcard сертификаты не выдаются при уровне валидации Extended Validation (EV), который используют крупные организации.

  • Code Signing сертификаты - это цифровые сертификаты, предназначенные для подтверждения подлинности и целостности программного обеспечения. Они позволяют разработчикам подписывать исполняемые файлы (программы) и скрипты, обеспечивая пользователей гарантией, что код не был изменён после подписания и действительно принадлежит указанному издателю.

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

    Используя публичный ключ из сертификата подписи кода, ОС пользователя дешфирует цифровую подпись и сравнит самостоятельно расчитанный хэш с дешифрованным, тем самым проверяя целостность и неизменность подписанной программы/скрипта. После чего, обратившись к сертификату удостоверяющего центра, будет проверена авторизованность выданного издателю программы сертификата.
    Таким образом, мы снова наблюдаем эту цепь доверия, где сертификат корневого центра (установленный в хранилище ОС) заверяет сертификат удостоверяющего центра, удостоверяющий центр заверяет сертификат субъекта, а сертификат субъекта заверяет подпись кода.

    Отличается данный сертификат несколькими полями: в Subject.CommonName теперь указано имя организации-издателя программы, поле расширения Key Usage содержит идентификатор значения digitalSignature, а вот поле расширения Extended Key Usage уже содержит идентификатор для уточнённого использования ключа сертификата - codeSigning.

  • CA-сертификаты (сертификаты удостоверяющих центров) - предназначены для подписания других сертификатов в инфраструктуре открытых ключей (PKI).
    Отличаются такие сертификаты значениями нескольких полей, среди них Basic Constraints, где BasicConstraints.cA = true, т.е. сертификат является CA и может подписывать иные сертификаты, а также значение BasicConstraints.pathLenConstraint может ограничивать максимальную длину цепи сертификации.
    Поле Key Usage содержит значение keyCertSign, тем самым позволяя использовать ключ для подписи других сертификатов, а также может обладать значением cRLSign для подписи CRL - списка отозванных сертификатов. Если для отслеживания отозванных сертификатов используется протокол OCSP, то в Extended Key Usage может находиться флаг OCSPSigning

    О цепочке доверия

    Сертификаты, заверяющие другие сертификаты формируют то, что называется chain of trust (цепь доверия / цепь сертификации). Это можно сравнить с заверкой документов - в данном случае каждый "заверяемый" сертификат может сам заверять другие сертификаты, при условии что изначальный корневой "нотариус" является известным проверяющему доверенным сертификатом. Цепь доверия позволяет проверить каждый её сертификат снизу вверх, от самого "младшего" сертификата (обычно это так называемый End-Entity сертификат, например TLS-сертификат веб-сервера) через промежуточные сертификаты (используемые для подписи других сертификатов) вплоть до корневого, которому проверяющий доверяет по умолчанию и который "заверяет" всю цепочку (при условии что на пути к нему не было ошибок/истёкших сроков действия и т.д.).

    • Формирование цепочки доверия начинается с корневого сертификата, называемого Root CA Certificate, который является самоподписным. Держателями таких сертификатов выступают специальные организации, основной задачей которых является обновление собственных корневых сертификатов, безопасное хранение приватных ключей и наделение прочих организаций полномочиями удостоверяющего центра (путём подписи их промежуточных сертификатов ключами из корневого).

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

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

      Как уже говорилось в разделе про самоподписанные сертификаты, корневой сертификат, всегда являющийся самоподписанным, может быть и "локальным", например корпоративные сертификаты, используемые компанией для авторизации доступа к её инфраструктуре, в этом случае сотрудник-администратор при помощи Root CA программного обеспечения выпустит корневой сертификат, который будет устанавливаться на корпоративные устройства и верифицировать все производные от него сертификаты в рамках инфраструктуры компании.

      Да, если вы слышали об проходившей в России "установке сертификатов Минцифры" то, думаю, что теперь вам понятна цель этого мероприятия - корневые ГОСТ-сертификаты от Минцифры вряд ли попадут с системными обновлениями в менеджеры сертификатов Firefox / Windows / т.п., поэтому пользователей просят вручную их установить для доступа к сервисам (например веб-сайтам банков), которые по каким-либо причинам используют сертификаты находящиеся в цепи доверия от корня Минцифры.

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

      Промежуточные сертификаты нужны для удобства, делегирования выдачи, безопасности и масштабрования PKI. Потенциальные организации-субъекты промежуточных сертификатов проходят строгие проверки, после чего промежуточный сертификат подписывается приватным ключом корневого центра, и субъект получает возможность использоать свой сертификат уже для выдачи и подписи прочих сертификатов, избавляя от необходимости это делать корневой центр, который, как уже было сказано, находится в режиме повышенной безопасности.

      Промежуточные сертификаты позволяют подписывать и выдавать конечные сертификаты (End-Entity Certificate), которые уже являются описываемыми "клиентскими" TLS-сертификатами, сертификатами для подписи кода и т.д.. Конечные сертификаты не являются CA-сертификатами, поскольку не могут использоаться для подписи иных сертификатов.

  • И некоторые другие области применения, например: Email-сертификаты, используемые в рамках S/MIME протокола для проверки целостности полученного письма а также его расшифровки (S/MIME зачастую используется(-лся) внутри организаций с собственными самоподписными сертификатами), сертификаты дляэлектронной подписи документов, выдаваемые гражданам государственными органами для возможности удалённо подписывать документы (некоторыми государствами для ЭЦП используется второй стандарт сертификатов PGP с "сетью доверия") и другие.

По уровню валидации

Чем выше уровень валидации, тем более "надёжным" является сертификат, но при этом субъекту требуется предоставить больше информации и пройти строгие проверки. Уровни валидации делятся на:

  • Domain Validation (DV) - выдаётся для подтверждения владения доменом(ами) системы доменных имён (DNS). Перед выдачей, выдающий центр должен убедиться в факте владения доменом. Если вы перейдете на любой сайт в веб-браузере, то увидите какие доменные имена принадлежат его администрации посмотрев поля сертификата Subject \ Subject Alternative Name. Является самым распространённым уровнем валидации сертификатов, поскольку обеспечивает необходимый минимум для работы используемого на всех веб-сервисах протокола TLS, необходимого для функционирования HTTPS. TLS-клиенту веб-браузера при переходе по URL и установке соединения необходимо убедиться, что доменное имя принадлежит веб-серверу и сертификат, подтверждающий это, не отозван/просрочен. Для других применений (например, code signing) такая валидация не подходит, поскольку доказывает лишь факт владения некоторыми доменами, личность держателя сертификата не проверяется и он может преследовать любые цели.

    Распространённость объясняется простотой и автоматизированностью процесса валидации, желающему получить сертификат достаточно ответить на электронное письмо, отправленное на административный адрес домена / разместить определённый файл на веб-сервере / добавить определённую запись на работающий DNS-сервер. Особо популярная организация Let's Encrypt осуществляет полностью бесплатную и автоматизированную выдачу DV-сертификатов сроком на 90 дней. Подобная простота и доступность существенно повлияла на развитие веб-сервисов за последнее десятилетие и позволила отказаться от незащищённого протокола HTTP, поскольку любому веб-сервису стала доступна сертификация, необходимая для TLS, и, следственно, HTTPS. Однако, у доступности есть и негативные последствия - например с ростом количества выданных сертификатов растёт и количество отозванных, что увеличивает размер загружаемых CRL-списков и замедляет проверку действительности сертификата конечными устройствами.

  • Organization Validation (OV) — помимо права владения рассматриваемым доменным именем также содержит подтверждение легального и физического существования организации, такие сертификаты содержат помимо прочего юридическое название и местоположение организации. Валидация этих данных производится вручную сотрудником выдающего центра (посредством проверки официальных документов), хотя часть может быть проверена автоматизированными стредствами. Как можно догадаться, такие сертификаты используются организациями и бизнесом для работы TLS на корпоративных веб-серверах, для предоставления чувствительного (а значит требующего дополнительной верификции) Business-to-Business API, подписи кода и т.д.. Этот и следующий (EV) вид сертификатов может быть использован для подписи программ/кода (code signing), поскольку в данном случае подтверждается факт существования компании-издателя программы, в отличие от предыдущих видов валидации, за которыми может стоять неизвестное лицо. Однако отмечу, что в отдельный операционных системах проверку издателя может проходить только описываемый далее EV сертификат (насколько мне известно, OV-сертификаты не считаются доверенными в Windows).

  • Extended Validation, (EV) - подтверждает право владения рассматриваемым доменом, а также юридическую информацию об организации, факт её существования и физического адреса и наличие соответствующих полномочий у лица, которое запросило сертификат. Валидация этих данных осуществляется вручную сотрудником центра сертификации, исходя из всего перечисленного можно сделать вывод, что это самый "надёжный" вид сертификатов, он используется банками, крупными компаниями и e-commerce организациями для функционирования TLS на веб-серверах, подписи кода издаваемых программ, защиты внутренних соединений и т.д.. До недавних пор вы могли наблюдать как браузеры подсвечивали зелёным цветом некоторые URL в адресной строке, например сайты банков/госучреждений, что означало наличие EV-сертификата у веб-сервера.

  • Individual Validation (IV) - не очень распространённый тип сертификата, используемого в основном для подписи кода исполняемых программ, выдаваемый после проверки личности физического лица. В отличие от сертификатов с проверкой организации (OV) или расширенной проверкой (EV), IV-сертификаты предназначены для индивидуальных разработчиков, не зарегистрированных как юридические лица. Проверка производится путём предоставления фото документов личности вместе с фото лица/иными средствами верифицировать человека. Обычно используется индивидуальными разработчиками для подписи приложений (code signing), хотя не все операционные системы считают подобные сертификаты надёжными. В России, на момент написания материала получение международных IV сертификатов недоступно.

Проверка сертификата

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

DigiCert Root CA (self-signed root CA certificate)
  ↑
DigiCert Intermediate CA 1 (intermediate CA certificate)
  ↑
DigiCert Intermediate CA 2 (intermediate CA certificate)
  ↑
example.com (end-entity certificate)

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

  1. Клиент (веб-браузер) подключается к веб-серверу example.com. Во время установки TLS-соединения, сервер отправлят сообщение Certificate, содержащий сертификат непосредствено example.com (т.н. "листовой", "leaf certificate", нам он известен как конечный или End-Entity Certificate), а также, зачастую сервера отправляют сертификаты всех промежуточных удостоверяющих центров, в нашем случае веб-сервер отправит TLS-сертификат example.com, а также промежуточные сертификаты DigiCart Intermediate 2 и подписавший его DigiCart Intermediate 1.

  2. Клиент получает сертификаты и восстанавливает цепочку доверия: начиная с листового (TLS) сертификата просматривется поле Issuer, содержащее информацию о выдавшем сертификат центре, и ищется сертификат, Subject которого соответствует этому значению (данные поля сравниваются по находящимся в них структурам Distinguished Name, которые мы рассматривали ранее в таблице). Помимо этого, сертификаты удостоверяющих центров могут находиться по соответствию полей authorityKeyIdentifier(содержит хэш публичного ключа сертификата вышестоящего центра) и subjectKeyIdentifier(содержит хэш публичного ключа сертификата, в котором находится). На самом деле, в зависимости от реализации, данный шаг может быть разбит на несколько шагов по мере работы алгоритма, главное что нужно понимать - сопоставляя сертификаты клиент восстанавливает всю цепочку доверия от младшего выданного к старшему выдавшему, не считая корневого сертификата, который не отправляется.

  3. Если каких-то сертификатов не хватает (не были отправлены сервером), клиент может обратиться (при наличии) к полю сертификата Authority Information Access (AIA), где указан URL для загрузки родительского сертификата. Например, сервер не отправит сертификат DigiCert Intermediate CA 1, поэтому по URL-адресу из AIA поля сертификата DigiCert Intermediate CA 2 (который является "дочерним" по отношению к искомому) будет загружен его "родительский" Intermediate CA 1 сертификат.

  4. Последний сертификат для полной цепочки доверия - корневой. Данный сертификат не отправляется вместе с остальными, поскольку чтобы быть доверенным, корневому сертификату необходимо уже находиться в хранилище сертификатов клиента. Корневой сертификат ищется как значение из поля Issuer в самом "верхнем" промежуточном сертификате (в нашем примере DigiCert Intermediate CA 1).

  5. Теперь, когда у клиента есть "заякоренная" (поскольку корневой сертифика это т.н. "trush anchor") цепочка сертификатов, он может приступить к её верификации.

  • Для каждого сертификата расшифровывается его цифровая подпись из поля Signature по алгоритму из Signature Algorithm, используя публичный ключ из поля Subject Public Key Info подписавшего (т.е. вышестоящего в иерархии) сертификата центра. Затем расчитывается хэш проверяемого сертификата по алгоритму из Signature Algorithm и сверяется с расшифрованным значением. Проверка продолжается вплоть до корневого, который является доверенным по умолчанию и ключ которого заверяет самый вышестоящий промежуточный сертификат. Например, Signature из конечного TLS-сертификата example.com расшифровывается по алгоритму Signature Algorithm с использованием публичного ключа из сертификата DigiCert Intermediate CA 2. То же самое проделывается для самого DigiCert Intermediate CA 2 и DigiCert Intermediate CA 1.

  • Проверяется срок действия из поля Validity.

  • Проверяются поля-расширения, например для CA-сертификатов проверяется поле Basic Constraints, где BasicConstraints.cA = true, т.е. сертификат является CA и может подписывать иные сертификаты, а реальная длина цепочки доверия не превышает значение BasicConstraints.pathLenConstraint.

  • Также проверяются поля-расширения Key Usage / Extended Key Usage, где для TLS-сертификата веб-сервера указаны значения digitalSignature, keyAgreement и serverAuth.

  • Для TLS-сертификатов в зависимости от доменного имени веб-сервера, к которому идёт подключение, проверяются дополнительные доменные имена при наличии поля Subject Alternative Names.

  • При необходимости и в зависимости от вида сертификата могут проверяться Name Constraints, Policy Constraints, и прочие поля.

  1. Сертификаты проверяются на предмет отзыва, либо посредством загрузки СRL-списка по URL из поля CRL Distribution Points (или же дельта-списка из поля Freshest CRL), после чего серийный номер проверяемого сертификата ищется в загруженном списке отозванных сертификатов, либо используя протокол OCSP посредством запроса серийного номера сертификата на OCSP-сервер, URL к которому указан в поле Authority Information Access (AIA).

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

Отзыв сертификатов

Сертификат может быть отозван перед истечением своего срока (значений поля Validity), что будет означать что сертификат более не валиден и не доверие к нему аннулированно. Отзыв сертификатов является одной из ключевых мер безопасности в PKI, поскольку не позволяет злоумышленникам использовать скомпрометированные данные и недействительный сертификат в своих целях.
Сертификат может быть отозван по ряду причин:

  • Компрометация ключа — приватный ключ (либо субъекта, либо CA) стал известен злоумышленникам. В случае компрометации центра сертификации (CA), отзываются все выданные и подписанные им сертификаты.

  • Изменение данных субъекта — юридический статус, название или адрес организации изменились.

  • Смена/аннулирование полномочий — право создания электронной подписи, право владения доменным именем или другие атрибуты утрачены.

  • Замена (называемая "certificate superseeded") - выпущен новый сертификат вместо старого (например, при повышении уровня валидации). Старый более не является доверенным.

  • Временная приостановка — сертификат может быть "приостановлен", подобный статус называется "Certificate Hold", например при возможной утечке приватного ключа или проверке центром дополнительных сведений о сертификате. Затем сертификат может быть восстановлен.

  • Прекращение деятельности — субъект ликвидирован или больше не нуждается в сертификате.

  • Обратите внимание, что сертификат с истёкшим сроком действия НЕ является отозванным.

Для получения информации и проверки актуальности сертификата используются 2 протокола:

  • CRL (Certificate Revocation List) - это список (в формате X.509 v2 CRL), который выпускается центром сертификации (CA) и содержит серийные номера сертификатов, которые были отозваны до окончания срока их действия. CRL списки, как и сертификаты, подписываются приватным ключом центра сертификации и могут быть проверены используя сертификат самого центра (в сертификате подписывающего CRL-лист есть даже специальное значение поля расширения KeyUsage - cRLSign). CRL обновляется центром сертификации с определённой периодичностью, внося туда информацию о новых отозванных сертификатах, при этом CRL списки обладают жизненным сроком (обычно 24 часа), по истечении которого список считается устаревшим. Обычно CRL центра сертификации содержит ранее выданные им же сертификаты, однако это не обязательно и отозванный сертификат может находиться в списке, управляемом другим центром.

    Чтобы проверить не является ли сертификат отозванным, клиент (например, веб-браузер) извлекает из него ссылку на CRL из поля CRL Distribution Point и загружает по ней CRL-файл (обычно через HTTP), содержащий полный список отозванных сертификатов (альтернативно может быть использована ссылка из поля Freshest CRL, содержащая т.н. дельта-CRL, то есть список содержащий только отличия от ранее загруженного полного списка, тем самым процесс проверки ускоряется, однако на устройстве должен уже находиться полученный ранее список). Далее проверяется подпись CRL, чтобы убедиться, что он был выпущен доверенным центром сертификации.

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

  • OCSP (Online Certificate Status Protocol) — это сетевой протокол, позволяющий в реальном времени получить статус цифрового сертификата. Из поля проверяемого сертификата Authority Information Access извлекается URL, на который клиент (например, веб-браузер) отправляет HTTPS-запрос с серийным номером сертификата. OCSP-сервер (обычно управляемый центром, выдавшим сертификат) отправляет ответ, подписанный приватным ключом центра сертификации (у такого центра в сертификате есть значение OCSPSigning в поле Extended Key Usage), который содержит один из трёх статус-кодов: good — сертификат действителен, revoked — отозван, unknown — информации нет. Если подпись ответа валидна и статус в ответе good - сертификат не является отозванным.

Несмотря на то, что описываемые методы кажутся полноценным решением задачи - на самом деле RFC 9325 говорит о том, что на сегодняшний день механизм отзыва сертификатов, а точнее получение информации о нём - далёк от совершенства.
У каждого из методов есть свои недостатки - CRL список обновляется с периодичностью, а значит существует некоторое окно для злоумышленника чтобы эксплуатировать отозванный сертификат, пока запись о недействительности сертификата не была опубликована центром выдачи. Кроме этого, CRL списки огромны и продолжают расти вместе с количеством выдаваемых сертификатов, из-за этого загрузка файлов, содержащих CRL-списки зачастую оказывается ресурсоёмкой для конечных устройств. Кроме того может быть ситуация когда загруженный ранее список считается истёкшим, а актуальный загрузить невозможно из-за отсутствия подключения к сети. На самом деле многие производители ПО считают CRL списки устаревшим методом ввииду задержки обновления и большого объема загружаемых данных и попросту их не используют.

OCSP позволяет получить более актуальные сведения о статусе сертификата и оперирует куда более меньшими объёмами информации, однако также обладает рядом недостатков, в числе которых невозможность отправки запроса при проблемах с сетью (например, вследствие DDoS-атаки), ответы конечно могут кэшироваться на случай сбоев сети, но тогда велик риск устаревания ответа, помимо этого - атаки типа "replay", когда отправленный ранее валидный ответ от OCSP-сервера записывается злоумышленником и затем повторно отправляется в ответ на перехваченный запрос клиента. Также клиент вынужден контактировать с OCSP сервером, таким образом управляющий OCSP-сервером может отследить какие сайты он посещают исходя из отправляемых на проверку TLS-сертификатов, что нарушает конфиденциальность клиента.

В случае невозможности получения информации о статусе сертификата, например ввиду перебоев в работе сети или намеренных атак на OSCP-сервера/сервера загрузки CRL, у клиентов есть 2 опции так называемой Failure-модели: считать сертификат по-умолчанию отозванным, а значит сервис недоступным, или же считать сертификат напротив, действительным. Большинство браузеров, например, выбирают второй вариант, предпочитая доступность безопасности. Помимо доступности это объясняется еще и тем, что при первом варианте появляется новый вектор DoS-атаки, когда атака и вывод из строя OCSP-сервера означает вывод из строя всех зависимых от него сервисов.

В попытках решить перечисленные проблемы были созданы еще 2 механизма проверки статуса сертификата, которые используются рядом ПО:

  • OCSP-stapling - расширение базового OCSP для TLS-соединений. Предоставляющий сертификат TLS-сервер самостоятельно направляет запросы о своём сертификате OCSP-серверу и кэширует ответы. Помимо перечисленного, такой OCSP-ответ содержит временную метку о том, когда ответ был создан (такой ответ обычно считается актуальным 24 часа), и также подписывается ключом ответственного центра сертификации. При установке TLS-соединения, если клиент отправляет ClientHello сообщение с расширением status_request, то сервер отправляет кэшированный OCSP-ответ в расширении CertificateStatus в своём сообщении ServerHello, избавляя клиента от необходимости осуществлять запрос самостоятельно, снижая нагрузку на OCSP-сервер и обеспечивая приватность клиента (данных о том, какие вебсайты он посещает). Это можно сравнить с разрешением на посещение какой-либо режимной территории, где у вас есть бумажка, указывающая, что в течении такого-то периода времени вы - авторизованное лицо.

  • CRLite - используется браузером Mozilla Firefox. Mozilla собирает все отозванные сертификаты от публичных центров сертификации и с их помощью на сервере Mozilla генерируется легковесный фильтр Блума - это вероятностная структура данных, не возвращающая ложных отрицаний (если говорит "не в списке" — точно не в списке), но иногда дающая ложные срабатывания ("возможно в списке" — не гарантировано). Этот фильтр публикуется и доставляется в браузер как часть обновлений Firefox. При открытии TLS-соединения, Firefox извлекает серийный номер сертификата и проверяет, есть ли он в фильтре Блума - если нет — сертификат точно не отозван, а если да — Firefox может сделать OCSP-запрос для уточнения (в режиме soft-fail), либо считать сертификат отозванным, если фильтр настроен на строгость. Таким образом, браузер может проводить быстрые проверки используя компактный фильтр Блума, а в случае погрешности переходить к уже более консервативому методу через OSCP.

Бонус: о фильтре Блума

Данная информация не относится к теме сертификтов, но мне просто стал интересен принцип работы фильтра Блума.

Сперва тот, кто формирует фильтр, определяет некоторый массив (последовательность) бит, скажем 128 бит. Затем определяется, например, 10 разных хэш-функций, которые будут преобразовывать серийные номера отозванных сертификатов в число от 0 до 127, полученные числа будут выступать индексами в массиве бит. После этого каждый серийный номер прогоняется через каждую хэш функцию и по полученному от неё индексу в массиве бит выставляется значение 1.

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

Таким образом, в 16 байт полученного фильтра мы могли бы уложить достаточно большое количество серийных номеров, при правильном подборе длины последовательности и хэш-функций - фильтр Блума оказывается крайне полезен. Думаю не нужно говорить, что объяснение на серийных номерах сертификатов а также длина последовательности в 128 бит и 10 хэш функций - это просто взятый из воздуха пример, фильтр Блума применяется много где и конфигурируется по-разному.

Заключение

Надеюсь, что данный материал оказался полезным если не с прикладной, то с теоретической точки зрения. Всё-таки, сертификаты это одна из технологий, отвечающих на вполне философский вопрос - кому можно верить и почему.

Комментарии (0)