Structure of an SSL (X.509) certificate

Электронный сертификат X. 509 обзор

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

Сертификат X.509 версии 1 и 2

Версия 1 стандарта X.509 была издана в 1988
году. Версия 2 стандарта X.509 была издана в
1993 году и содержала минимальные
дополнения к версии 1. Приведенный ниже
рисунок показывают формат сертификатов
версии 1 и 2.

Данное поле описывает версию
сертификата. При использовании
дополнений версия должна быть
установлена как X.509 version 3 (значение равно
2). Если дополнения не используются,
версия должна быть 1 (значение должно
быть не установлено).

Идентификатор алгоритма ЭЦП

Поле содержит идентификатор
криптографического алгоритма,
используемого ЦС для выработки ЭЦП
сертификата.

Серийный номер сертификата

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

Имя Издателя сертификата

Поле Издатель идентифицирует
объект (субъект), который сформировал
ЭЦП и издал сертификат. Значение в поле
Издатель должно содержать ненулевое
значение DN (distinguished name). Поле Издатель
определено в рекомендациях X.501 как
тип Name. Значение поля состоит из
набора иерархических атрибутов (AttributeType),
таких как код страны и соответствующего
ему значения (AttributeValue, например, UA).
Тип компонентов AttributeValue, входящих в
имя, определяется типом атрибута AttributeType
и в основном используется DirectoryString.

Срок действия сертификата

Данное поле определяет срок действия (в
виде временного интервала) в течение
которого ЦС управляет сертификатом (отслеживает
состояние). Поле представляет
последовательность двух дат: дата
начала действия сертификата (notBefore) и
дата окончания срока действия
сертификата (notAfter). Оба этих значения
могут быть закодированы либо как UTCTime,
либо как GeneralizedTime.

Имя Владельца сертификата

Поле Владелец идентифицирует объект (субъект),
являющийся обладателем секретного
ключа, соответствующего открытому ключу
в сертификате.

Открытый ключ Владельца

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

Уникальный идентификатор Издателя и
Владельца

Данное поле может использоваться
только в сертификатах версии 2 или 3. Поле
было предусмотрено в версии 2
сертификатов X.509 для целей обеспечения
использования одинакового имени Владельца
или Издателя в разных
сертификатах. С введением дополнений в
версии 3 такая необходимость отпала.

Сертификат X.509 версии
3

Данный раздел описывает версию 3
сертификата X.509. Версия 3 описала
механизм дополнений, дополнительной
информации, которая может быть помещена
в сертификат. X.509 и рекомендации RFC 2459
описывают набор стандартных
дополнений, но вместе с тем не
ограничивают возможности использования
любых других дополнений путем
регистрации идентификатора (ISO или IANA).

Каждое дополнение состоит из трех
полей:

Таким образом, дополнение
представляет собой структуру,
содержащую:

  • идентификатор дополнения
  • признак «критичное/не критичное дополнение
  • собственно значение дополнения,
    представленное в бинарном виде (OCTET
    STRING)

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

Рекомендации  определяют основной
целью критичных дополнений —
предохранить сертификат, изданный ЦС, от
возможности использования его в
приложениях, которые не могут
обработать такие дополнения. Таком
образом, правила обработки дополнений,
изложенные в рекомендация, требуют от
прикладного ПО отвергнуть сертификат,
если дополнение отмечено критичным и
прикладное ПО не может его
интерпретировать. В свою очередь,
требование отвергнуть дополнение
прикладным ПО, отмеченное как критичное,
при невозможности его интерпретации,
требует от прикладного ПО детального
разбора дополнений сертификатов и
затрудняет процесс модификации как
прикладного ПО, так и ПО,
обеспечивающего реализацию ИОК.

Дополнения X.509 версии 3

Стандартные дополнения можно
разделить на две категории: ограничивающие
дополнения и информационные
дополнения. Первые ограничивают область
применения ключа, определенного
сертификатом, или сам сертификат. Вторые
содержат дополнительную информацию,
которая может быть использована в
прикладном ПО пользователем
сертификата.

К ограничивающим дополнениям
относятся:

  • базовые ограничения (basicConstraints);
  • область применения ключа (keyUsage);
  • расширенная область применения
    ключа (extendedKeyUsage);
  • регламенты сертификата (модифицируемые
    ограничениями регламентов и
    соответствием регламентов) (certificatesPolicies);
  • ограничения имен (nameConstraints).

К информационным дополнениям
относятся:

  • идентификаторы ключей (subjectKeyIdentifier,
    authorityKeyIdentifier);
  • альтернативные имена (subjectAltName,
    issuerAltName);
  • точка распространения СОС (cRLDistributionPoint,
    issuingDistributionPoint);
  • способ доступа к информации ЦС (authorityAccessInfo).

Идентификатор ключа Издателя

Дополнение Идентификатор ключа
Издателя (authorityKeyIdentifier) используется
для идентификации открытого ключа,
соответствующего секретному ключу ЭЦП,
использованному Центром Сертификации
при подписи издаваемого сертификата (или
СОС). Данное дополнение может быть
использовано в случае, когда Издатель
сертификата (ЦС) имеет несколько
различных секретных ключей ЭЦП (например
при плановой их смене), а так же для
однозначного построения цепочек
сертификатов. 
Функция построения цепочки
сертификатов использует значение
данного дополнения для однозначного
определения сертификата Издателя.

Идентификатор ключа Владельца

Данное дополнение используется для
идентификации различных сертификатов,
содержащих открытый ключ. Для упрощения
процедуры построения цепочки, данное
дополнение должно устанавливаться во
всех сертификатах ЦС, которые включают
дополнение basicConstraints с установленным
значением cA TRUE. Во всех издаваемых ЦС
сертификатах значение keyIdentifier в
дополнении authorityKeyIdentifier должно быть
идентично значению subjectKeyIdentifier сертификата
ЦС.
Для сертификатов, значение subjectKeyIdentifier должно
вырабатываться из открытого ключа или с
использованием метода генерации
уникальных значений. Рекомендациями RFC
2459 предлагается два метода генерации
идентификатора на основе значения
открытого ключа:

(1) Значение keyIdentifier определяется как 160
бит хэш-функции, вычисляемой по
алгоритму SHA-1 из значения BIT STRING subjectPublicKey
(исключая тэг, длину и неиспользованные
биты).

(2) Значение keyIdentifier определяется как 4-x
битовое поле со значением 0100 и
последующим за ним 60 битами наименьшей
значимой части хэш-функции, вычисляемой
по алгоритму SHA-1 из значения BIT STRING
subjectPublicKey.

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

Область применения ключа

Данное дополнение определяет область
применения секретного ключа,
соответствующего открытому,
содержащемуся в сертификате.

Таблица. Области применения
ключа

Расширенная область применения ключа

Срок действия секретного ключа

Данное дополнение позволяет Издателю
сертификата задать различные сроки
действия секретного и сертификата.
Дополнение содержит два опциональных
компонента: notBefore и notAfter. Секретный
ключ, соответствующий открытому в
сертификате, не должен быть использован
до или после времен, указанных
соответствующими компонентами. ЦС не
должен формировать сертификат, в
котором не указан не один из компонентов.

Регламенты использования сертификата

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

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

Регламенты использования
сертификата аналогичны делению
сертификатов на различные типы и
устанавливаются в соответствующем
стандартном дополнении всех
сертификатов конечных пользователей.

Таблица. Информация о
Регламенте сертификата

Данное дополнение предназначено для
использования в сертификатах ЦС. Оно
содержит список парных Идентификаторов
Объектов (OID). Каждая пара в свою
очередь включает Регламент Зоны
Издателя (issuerDomainPolicy) и Регламент
Зоны Владельца (subjectDomainPolicy). Такая
парность означает, что ЦС, выступающий в
роли Издателя (issuing CA), принимает Регламент
Зоны Издателя эквивалентным Регламенту
Зоны Владельца для подчиненного ЦС (subject
CA).
Пользователи, относящиеся к Издающему
ЦС (issuing CA) могут принимать Регламент
Зоны Издателя(issuerDomainPolicy) для
соответствующих приложений. Дополнение Соответствие
Регламентов ставит в известность
пользователей Издающего ЦС о том наборе Регламентов,
subject CA) которые сравнимы с
регламентами, соответствующими их
требованиями.

Альтернативное имя Владельца

Дополнение Альтернативное Имя
Владельца может использоваться для
двух целей. Во-первых, оно позволяет
расширить границы идентификации
Владельца сертификата. Для этого
используются заранее определенные
идентификаторы, которые включают адрес
электронной почты Internet, имя в DNS, IP адрес
и URI. Во-вторых, оно предоставляет набор
дополнительной справочной информации о
Владельце сертификата. Для этого
используется представление имени в
различных видах и множественное
представление имен. При необходимости
введения такой дополнительной
идентификации в сертификат должно
использоваться дополнение Альтернативное
Имя Владельца или Альтернативное
Имя Издателя

В связи с тем, что альтернативное имя
может быть использовано для целей
определения соответствия Владельца и
открытого ключа, все части
идентифицирующие его и входящие в
альтернативное имя, должны быть
проверены ЦС. Уровень проверки
дополнительной информации определяется
Регламентом ЦС.
Альтернативное Имя Владельца может
быть ограничено тем же способом, что и
поле Владелец в сертификате,
используя дополнение nameConstraintsExtension.

В соответствии с рекомендациями X.681
синтаксис поля определен в следующем
виде:

Альтернативное имя Издателя

Так же как и  дополнение Альтернативное
Имя Владельца, дополнение Альтернативное
имя Издателя (issuerAltName) служит целям
дополнительной ассоциации Издателя сертификата.
Правила использования данного
дополнения аналогичны использованию
дополнения Альтернативное Имя
Владельца.

Атрибуты Справочника Владельца
сертификата

Дополнение предусмотрено для хранения
дополнительной информации, связанной с
атрибутами директории X.500. Дополнение Атрибуты
Справочника Владельца сертификата не
рекомендуется использовать
рекомендациями RFC 2459, но он может быть
использован в частных реализациях.

Дополнение Базовые ограничения идентифицирует,
является ли Владелец сертификата
Центром Сертификации, и какова длина
цепочки сертификатов для этого ЦС.
Поле pathLenConstraint имеет смысл только
при условии, если значение cA установлено
в TRUE. В этом случае оно обозначает
максимальное количество сертификатов
ЦС, которые следуют за данным
сертификатом в цепочке. Значение нуль
означает, что только сертификаты
конечного пользователя могут следовать
в цепочке за данным сертификатом. При
использовании, значение pathLenConstraint
больше или равно нулю. Если значение не
установлено, это означает, что лимит на
длину цепочки не определен.

Читать также:  Этот сайт не имеет сертификата как исправить

Дополнение Ограничение имени,
должно использоваться только в
сертификатах ЦС. Оно указывает
пространство имен, внутри которого
должны быть расположены все имена
Владельцев издаваемых сертификатов.
Ограничения могут быть применимы как
имени Владельца (Subject DN), так и к
альтернативному имени. 
Ограничения определены в терминах
допускаемого (permittedSubtrees) или
исключаемого (excludedSubtrees) поддерева
имен. Любое имя совпадающее с
ограничением в исключающем поддереве
является некорректным, в независимости
от возможного его присутствия в
допускаемом поддереве.
При реализации данного дополнения RFC 2459
рекомендуется:

  • не использовать поля minimum и maximum ни
    в какой из форм имен, так что minimum всегда
    нуль, а maximum всегда отсутствует;
  • использовать только поля permittedSubtrees для
    задания разрешенного диапазона имен и
    не использовать excludedSubtrees, что
    согласуется с организационной или
    территориальной схемой иерархии.

Данное дополнение может быть
использовано в сертификатах, издаваемых
для ЦС. Дополнение Ограничение
регламента накладывает ограничения
на проверяемую цепочку в двух
направлениях. Оно может использоваться
для запрещения проверки соответствия
регламентов (policy mapping) или требовать,
чтобы каждый сертификат в в цепочке
содержал приемлемый идентификатор
регламента (policy identifier).

Точка распространения СОС

Точка распространения СОС является
дополнением, которое определяет
механизм и расположение СОС
определенного типа в сети,  и
определяет зону действия СОС как:

  • только для конечных пользователей,
  • только для ЦС,
  • или ограничивает коды мотивации.

Коды мотивировки, ассоциированные с
точкой распространения, должны
специфицироваться в поле onlySomeReasons.
Если поле onlySomeReasons отсутствует,
точка распространения должна содержать
отзываемые сертификаты для всех кодов.
ЦС может использовать Точку
распространения СОС как основу для
управления потоками данных при
компрометации. В этом случае, отзывы
сертификатов с кодами keyCompromise (1) и cACompromise
(2) располагаются в одной точке
распространения, а все остальные в
другой.

Способ доступа к информации ЦС

Данное дополнение указывает на
способы доступа к информации и сервисам
ЦС, издавшим сертификат, в котором это
дополнение установлено. Информация и
сервис могут включать процедуры on-line
проверки и получения Регламента (Регламентов)
ЦС. Способ получения СОС не
специфицируется данным дополнением, для
этого используется дополнение cRLDistributionPoints.

Четыре года назад я написал статью Человеческим языком о цифровых сертификатах: ASN.1, X.509, PKI, в которой постарался максимально понятно рассказать о цифровых сертификатах с примерами их использования через консоль и openssl. С того времени многое изменилось: openssl версии 1 ушёл в массы, появились и стали активно использоваться его форки (libressl и boringssl), появилась (типа) поддержка гостовских алгоритмов. Плюс я получил неожиданно много обратной связи, чего совершенно не ожидал, и в итоге появился этот полностью переработанный и актуализированный текст.

*Целевая аудитория этой статьи — айтишники, поверхностно знакомые с понятием цифрового сертификата и сопутствующими понятиями и техническими стандартами (X.509, PKI, PKCS). Текст не является пересказом документации или сборником рецептов, воспринимайте его как короткий учебник, рассказывающий о базовых концептах криптографии и сложившейся вокруг стандарта X.509 инфраструктуры.

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

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

Текст состоит из двух частей: достаточно подробная теоретическая основа (включая несколько базовых понятий из криптографии) и практическая часть с конкретными примерами на openssl. Все новые понятия в тексте вводятся последовательно, а примеры из практической части используют файлы, созданные в предшествующих разделах. Я старался пользоваться официальной русской терминологией, принятой в стандартах и литературе.

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

Для полноценной работы вам понадобится linux с терминалом и установленным openssl версии 1.0 или выше. С некоторым оговорками подойдёт macos с терминалом (в macos последних версий установлен форк openssl под названием libressl).

Теория¶

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

Что такое openssl¶

OpenSSL — это опенсорсный набор библиотек и программ для работы с SSL/TLS и некоторыми распространёнными криптоалгоритмами. В этой статье мы будем работать только с программой openssl, она представляет собой коллекцию утилит (команд) для операций над крипто-объектами: ключами, сертификатами, зашифрованными данными.

OpenSSL — очень старая система, в ней огромное количество legacy-кода и legacy-интерфейсов. Различные команды из её состава принимают разные аргументы и имеют разную логику работы. Команд этих очень много и я не буду рассказывать о них, вместо этого я сфокусируюсь на конкретных задачах, в рамках которых буду давать примеры использования команд для её решения. Иногда путей для решения задачи будет несколько.

Что такое и зачем нужны сертификаты¶

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

В русском языке слово сертификат употребляется наравне со словами удостоверение, свидетельство; особенно это характерно для бюрократии, официальных текстов и государственных стандартов. Например, в российской Системе документов по аккредитации в документе СДА 06-2009 используется такое определение:

Удостоверение (сертификат) — документ, выданный органом по сертификации персонала, удостоверяющий компетентность специалиста в определенной области испытаний в соответствии с присвоенным уровнем квалификации.

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

Термин цифровой сертификат (digital certificate) означает, что первичная его форма — в виде байтов на диске, памяти компьютера, на носителе информации. Цифровой сертификат можно легко скопировать и полученная копия будет обладать всеми его свойствами. В основе цифровых сертификатов лежит криптография, именно с помощью криптоалгоритмов происходит работа с сертификатом на всех этапах его жизненного цикла: создание, использование, уничтожение. Без знания основ криптографии, хотя бы самых элементарных, невозможно полноценно понять суть и смысл цифровых сертификатов, поэтому я про них тоже расскажу.

В дальнейшем я под словом сертификат буду подразумевать исключительно цифровой сертификат.

Основы криптографии¶

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

Википедия нам даёт такое определение:

Криптогра́фия (от др.-греч. κρυπτός «скрытый» + γράφω «пишу») — наука о методах обеспечения конфиденциальности (невозможности прочтения информации посторонним), целостности данных (невозможности незаметного изменения информации), аутентификации (проверки подлинности авторства или иных свойств объекта), шифрования (кодировка данных).

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

В криптографии принято алгоритм алгоритм шифрования/дешифрования называть просто шифр (cipher). Считается, что шифр сам по себе не может быть секретным, его алгоритм должен быть общеизвестным, а секретность обеспечиваться ключом — специальным набором байтов, который определяет, как именно алгоритм будет зашифровывать/расшифровывать данные. Общеизвестность нужна для того, чтобы шифр могли исследовать специалисты, подтверждая или опровергая его надёжность.

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

Важным для нас вариантом асимметричного шифра является криптосистема с открытым ключом (public-key cryptography). В её основе лежат такие принципы:

  • ключ состоит из двух компонентов: закрытого ключа / private key (предполагается, что он секретный и тщательно охраняется) и открытого ключа / public key (который может и должен распространяться свободно по любым каналам);
  • открытый ключ вычисляется из закрытого простым способом, а вот обратная процедура (вычисление закрытого ключа из открытого) является чрезвычайно сложной, затратной и невыполнимой за разумное время на любом доступном оборудовании;
  • существует открытые, общеизвестные и надёжные алгоритмы, которые используют закрытый и открытый ключ для криптографических операций, например, для шифрования/дешифрования.

Часто закрытый ключ также называют приватным или секретным, открытый ключ называют публичным, но я в тексте буду придерживаться терминов закрытый/открытый.

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

  • предполагается, что у отправителя уже есть открытый ключ, а у получателя — закрытый (парный к открытому, естественно);
  • отправитель при помощи открытого ключа и алгоритма (шифра) шифрует данные и отправляет результат через открытые каналы;
  • получатель при помощи закрытого ключа расшифровывает данные и восстанавливает исходный текст.
Читать также:  Как установить личный сертификат? — Удостоверяющий центр СКБ Контур

Поскольку открытый ключ общеизвестен, любой человек может зашифровать при помощи него сообщение, а дальше подменить оригинальное. У получателя нет никакого способа автоматически проверить (то есть аутентифицировать), что полученное им сообщение не было изменено и пришло именно от нужного отправителя. И тут на помощь приходит вторая схема использования пары ключей — цифровая подпись / digital signature. Она используется для подтверждения авторства сообщения, то есть для аутентификации. Вот пример:

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

Алгоритм подписи чаще всего оперирует не с сообщением целиком, а с его дайджестом (digest), то есть «сжатым» при помощи алгоритма криптографического хеширования (например, SHA-1 или гостовского СТРИБОГ). И в целом схема выглядит так:

Structure of an SSL (X.509) certificate

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

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

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

Цифровой сертификат в общем случае — это набор байтов, состоящий из двух блоков: информационного (например, название веб-сайта, название организации и т.п.) и цифровой подписи для информационного блока. Цифровая подпись создаётся удостоверяющим центром (УЦ) / certification authority (CA) и таким образом удостоверяет аутентичность данных из информационного блока. Но каким образом удостоверяющий центр проводит проверки, что подписываемый сертификат содержит данные той персоны или организации, которая подаёт его для подписи? Каким образом клиенты проверяют достоверность цифровой подписи в сертификате? Обо всём этом я подробно расскажу. Но сначала начнём со стандартов.

Существует несколько бинарных форматов для представления сертификатов, однако в абсолютном большинстве случаев вам придётся иметь дело с X.509-сертификатами. Все остальные форматы нишевые и я про них здесь не буду рассказывать.

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

Существует также набор стандартов для криптографии с открытым ключом PKCS (Public Key Cryptography Standards). На данный момент в нём 15 стандартов, их принято обозначать как PKCS#1, PKCS#2 и т.д. С полным списком можно ознакомиться в википедии: https://en.wikipedia.org/wiki/PKCS, а я в тексте буду на нужные мне части ссылаться по мере необходимости.

Изначально стандарты семейства PKCS разрабатывались компанией RSA Security LLC в целях рекламы крипто-алгоритмов, патенты на которые были на руках у компании, поэтому в индустрии отношение к этому наборы было и остаётся настороженным.

В середине девяностых IETF и NIST сформировали рабочую группу Public-Key Infrastructure (X.509), которая позднее стала называться просто PKIX. В рамках рабочей группы были разработаны стандарты, детально описывающие, как нужно использовать X.509 на практике: RFC 3280 и его наследник RFC 5280.

Для описания структуры используемых данных чрезвычайно широко используется стандарт Abstract Syntax Notation One (ASN.1), фактически все типы данных в прикладной криптографии описаны через ASN.1-нотацию.

Используемые криптоалгоритмы¶

В инфраструктуре открытых ключей чаще всего используются RSA, DSA и ECC.

  • RSA — криптосистема, названная по первым буквам имён её создателей: Rivest-Shamir-Adleman. В основе её теории лежит сложная задача факторизации (разделения на множители) произведения двух очень больших простых чисел. Выбирается два случайных очень больших простых числа p и q, их произведение n = p · q называется модулем / modulus и длина модуля в битах задаёт длину закрытого ключа. Чем больше длина, тем более надёжным считается ключ. Также выбирается сравнительно небольшое простое число e (чаще всего это 65537), называемое открытой экспонентой / public exponent. Дальше из модуля n вычисляется по специальному алгоритму (который я тут не буду объяснять) закрытая экспонента / private exponent. В итоге формируется открытый ключ в виде пары чисел (e, n) и закрытый ключ в виде пары (d, n). Этот алгоритм долгое время был самым распространённым и по умолчанию фигурировал во всех инструкциях и мануалах. Однако в середине девяностых был разработан алгоритм для квантовых компьютеров, выполняющий факторизацияю чисел. Хотя квантовых компьютеров ещё нет, но теперь RSA считается потенциально слабым, если длина закрытого ключа меньше 2048 бит. RSA содержит алгоритмы как для шифрования, так и для цифровой подписи.
  • DSA — криптографический алгоритм, названием расшифровывается как Digital Signature Algorithm, то есть алгоритм цифровой подписи. Он основан на математической теории возведения в степень по модулю и задаче дискретного логарифмирования. В отличие от RSA, этот алгоритм может использоваться только для подписывания данных, но не для их шифрования. Исторически DSA использовался и продолжает использовать в операциях с государственными органами США, однако нас он не интересует, поэтому больше о нём не будем, просто имейте в виду, что он поддерживается при создании сертификатов тоже. DSA может использоваться только для цифровой подписи.
  • ECC (или просто EC) — набор криптосистем на основе теории эллиптических кривых над конечным полем. Сейчас эти виды шифров используется всё активнее вместо RSA, поскольку они быстрее, размер ключа значительно меньше, потенциально устойчивее к взлому на квантовых компьютерах. Эллиптическая криптография построена на основе набора алгебраических операций на эллиптической кривой, которые, в свою очередь, строятся на основе операций в конечном поле, над которым задана кривая. В общем, это такая хардкорная высшая математика, знать которую совсем не обязательно для использования шифров. Крипто-алгоритмов на основе EC достаточно много, часть из них была перенесена из старых классических крипто-систем, часть придумана заново. Например, алгоритм цифровой подписи ГОСТ 34.10-2018 также использует эллиптические кривые для работы. Некоторые из ECC-алгоритмов могут использоваться для шифрования, а некоторые для цифровой подписи.

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

Протокол Diffie-Hellman (Diffie–Hellman key exchange, дальше я буду его коротко называть DH) играет чрезвычайно большую роль в современной криптографии, поэтому я о нём расскажу подробно.

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

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

  • Алиса и Боб придумывают по секретному числу, например, Алиса выбирает 9, а Боб — 2.
  • Алиса и Боб через открытый канал договариваются о каком-нибудь общем целом числе, скажем, 18. Это число не является секретным, но при каждом сеансе DH оно должно быть новым. Самый простой способ договориться, когда сторона, начинающая коммуникацию, просто выбирает число и другая сторона его принимает.
  • Дальше каждая сторона складывает своё секретное число и общее число, у Алисы получается 9 + 18=27, а у Боба 2 + 18=20. Полученный результат каждый отправляет другой стороне по открытому каналу.
  • Полученное число Алиса и Боб складывают со своим секретным числом: у Алисы получается 20 + 9 = 29, а у Боба 27 + 2 = 29.
  • Вот это число 29 и является ключом, который каждая из сторон использует для шифрования/дешифрования.

Я выбрал операцию сложения ради простоты объяснения, в реальном протоколе используется сложно-обратимая операция. Если её обозначить через ⊕, то для произвольных значений X и Y вычисление Z = X ⊕ Y выполняется легко; а зная Z и X, вычислить Y исключительно сложно и затратно. В реальном DH используется функция возведения в степень в мультипликативной группе вычетов по простому модулю, её обратная операция — дискретный логарифм — считается крайне сложной и на данный момент не имеет эффективного решения.

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

Читать также:  Подарочные сертификаты на ювелирные изделия красноярск

Рассмотрим такую ситуацию: есть клиент и есть сервер, к которому подключается клиент через небезопасный и незащищённый канал. Также выбран некоторый криптоалгоритм цифровой подписи. У сервера есть закрытый ключ, а его открытая часть уже есть у клиента. Тогда аутентифицированный DH может работать, например, так:

  • Клиент генерирует случайное секретное значение X общее публичное значение A.
  • Клиент инициирует соединение к серверу и отправляет по нему A.
  • Сервер получает A, генерирует своё секретное значение Y и вычисляет публичное значение B на основе публичного значения A и своего секретного Y.
  • Сервер вычисляет общий секретный ключ K на основе публичного значения A и своего секретного значения Y.
  • Сервер вычисляет цифровую подпись S от объединённого набора значений A и B и отправляет клиенту публичное значение B и цифровую подпись S.
  • Клиент получает публичное значение B, вычисляет на основе B и своего секретного значения X общий секретный ключ K.
  • Клиент проверяет цифровую подпись K объединённого набора значений A и только что полученного B (помним, что у клиента уже есть открытый ключ сервера).
  • Если верификация подписи проходит успешно, вычисленный ключ K используется для шифрования и дешифрования данных между клиентом и сервером при помощи симметричного алгоритма.

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

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

Концепт CSR и подписывания сертификата удостоверяющим центром¶

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

Под личными данными заявителя я подразумеваю его имя, название организации, адрес, город и прочую информацию, которую в англоязычной терминологии принято называть identity.

Чтобы удостоверяющий центр создал сертификат с открытым ключом и личными данными заявителя, ему нужно убедиться как минимум в двух вещах:

  • Заявитель является именно тем, за кого себя выдаёт, то есть предоставленные им личные данные точно его или его организации, уполномоченным представителем которой он является.
  • У заявителя есть закрытый ключ для того открытого, который он предоставил удостоверяющему центру для подписи вместе с личными данными.

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

Вот этот вот информационный блок (состоящий из личных данных и открытого ключа) плюс цифровая подпись для него формируют запрос на подпись сертификата / certificate signing request (CSR). Для X.509 формат данных CSR определён в спецификации PKCS#10, он достаточно простой и по сути представляет собой линейный список информационных полей, поэтому я особо не буду углубляться в описание его формата.

В удостоверяющем центре после верификации CSR выделяют из всего блока личных данных нужные, дополняют их данными УЦ, после чего получившийся новый блок подписывают закрытым ключом УЦ и получается X.509-сертификат.

Все эти шаги я нарисовал на одной схеме:

Structure of an SSL (X.509) certificate

TBS Certificate расшифровывается как to be signed certificate, то есть, данные для подписи, подписываемый сертификат.

Такая инфраструктура называется Public key infrastructure (Инфраструктура открытых ключей) или сокращённо PKI.

Инфраструктура УЦ и сертификаты¶

X.509-сертификат состоит из стандартного набора полей, часть из них обязательна, часть нет. Официального перевода этих названий на русский нет, поэтому я преимущественно буду пользоваться оригинальными именами с пояснениями при необходимости.

В каждом X.509-сертификате есть два обязательных поля: issuer и subject. Поле subject (то есть субъект, в философском смысле: носитель деятельности, осуществляющий активность) содержит личные данные заявителя и по сути является названием сертификата, его главным идентифицирующим признаком, именем. Я специально не использую термин идентификатор, поскольку в контексте сертификата такое поле уже есть, причём оно является необязательным. Содержимое берётся из одноимённого поля в CSR при создании сертификата и обычно представляет собой имя персоны, организации или домен веб-сайта.

В поле issuer хранится имя сертификата удостоворяющего центра. Постоянно помним, что открытые ключи у нас распространяются исключительно внутри сертификата. Поэтому в поле issuer находится содержимое поля subject сертификата УЦ, внутри которого находится открытый ключ, закрытая часть которого используется для подписи сертификата заявителя.

Поля issuer и subject являются структурированными, то есть это не просто строчки текста, а оформленные в жёстко заданную структуру данные типа distinguished name. Об этом подробнее я расскажу в практическом разделе.

Таким образом любой сертификат A в подобной инфраструктуре подписан закрытым ключом, открытая часть которого записана в каком-то другом сертификате B. Для простоты обычно в таком случае говорят, что сертификат A подписан сертификатом B. В свою очередь сертификат B подписан сертификатом C и так далее. Образуется цепочка зависимостей, которая завершается сертификатом Z специального вида, в котором поля issuer и subject совпадают. Это означает, что сертификат Z подписан закрытым ключом, открытая часть которого записана в этом же сертификате. Он так и называется — самоподписанный сертификат (self-signed certificate).

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

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

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

В итоге, только удостоверяющие центры (certification authority) обладают сертификатами, которые можно использовать для подписывания других сертификатов, чтобы они могли включаться в цепочку доверия. Их принято называть CA-сертификатами (CA certificate). А финальный самоподписанный сертификат в цепочке доверия называется сертификатом корневого удостоверяющего центра или просто корневым сертификатом (root certificate).

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

Также в сертификате есть множество других полей, которые ограничивают его применение. Например, диапазон дат, внутри которых сертификат можно считать доверенным. Практически все системы помечают сертификат недоверенным, если текущая дата в системе лежит вне указанного в сертификате диапазона. Диапазон действия корневых сертификатов обычно очень большой, порядка 10-20 лет. Этот диапазон дат указывается в полях notBefore и notAfter.

Здесь нужно отметить, что интерпретация «срока годности» сертификата целиком лежит на стороне программного обеспечения, которое сертификат использует. Нет никаких объективных причин, по которым сертификат перестаёт быть доверенным после достижения некоторой даты. Однако ограниченный срок жизни гарантирует стабильный источник дохода удостоверяющим центрам, которые выписывают сертификаты за весьма большие деньги.

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

X.509 — стандарт очень гибкий и позволяет добавлять произвольные дополнительные поля помимо базовых, это делается через расширения (extensions), я о них подробнее расскажу в практической части.

Цепочки доверия сертификатов на примере¶

Понятнее всего будет объяснить цепочки доверия на примере веб-сайтов и браузера.

У каждого работающего через SSL/TLS сайта имеется X.509-сертификат, подтверждающий его identity. Когда браузер устанавливает первое защищённое соединение с веб-сервером, они обмениваются информацией об используемых криптоалгоритмах, в рамках этого обмена веб-сервер отдаёт браузеру набор сертификатов, в котором есть обязательно сертификат собственно сайта, а остальные — промежуточные сертификаты для построения цепочки доверия.

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *