Основы криптографии¶
Я не буду углубляться в детали, а лишь расскажу коротко и максимально доступно о ключевых криптографических концептах, лежащих в основе нашей темы. Хотя бы базовое их знание критично важно для полноценного понимания принципов работы цифровых сертификатов и сопутствующей инфраструктуры.
Википедия нам даёт такое определение:
Криптогра́фия (от др.-греч. κρυπτός «скрытый» γράφω «пишу») — наука о методах обеспечения конфиденциальности (невозможности прочтения информации посторонним), целостности данных (невозможности незаметного изменения информации), аутентификации (проверки подлинности авторства или иных свойств объекта), шифрования (кодировка данных).
Все эти аспекты используются при работе с сертификатами. Начнём с шифрования, в упрощённой форме это процесс преобразования открытого текста в зашифрованный и наоборот, из зашифрованного в открытый — этот процесс называется дешифрованием, дешифровкой, расшифровкой.
В криптографии принято алгоритм алгоритм шифрования/дешифрования называть просто шифр (cipher). Считается, что шифр сам по себе не может быть секретным, его алгоритм должен быть общеизвестным, а секретность обеспечиваться ключом — специальным набором байтов, который определяет, как именно алгоритм будет зашифровывать/расшифровывать данные. Общеизвестность нужна для того, чтобы шифр могли исследовать специалисты, подтверждая или опровергая его надёжность.
Если для шифрования и дешифрования используется один и тот же ключ, то такой алгоритм называется симметричным. Если для шифрования и дешифрования используются разные ключи, то алгоритм называется асимметричным. У каждого из таких типов есть свои области применения.
Важным для нас вариантом асимметричного шифра является криптосистема с открытым ключом (public-key cryptography). В её основе лежат такие принципы:
Часто закрытый ключ также называют приватным или секретным, открытый ключ называют публичным, но я в тексте буду придерживаться терминов закрытый/открытый.
Первая схема использования пары закрытого и открытого ключей — шифрование: отправитель шифрует текст, затем отправляет получателю зашифрованный текст через открытый канал, а получатель их расшифровывает снова в открытый текст. Эта схема предназначена для защиты информации, вот что для неё требуется:
Поскольку открытый ключ общеизвестен, любой человек может зашифровать при помощи него сообщение, а дальше подменить оригинальное. У получателя нет никакого способа автоматически проверить (то есть аутентифицировать), что полученное им сообщение не было изменено и пришло именно от нужного отправителя.
Алгоритм подписи чаще всего оперирует не с сообщением целиком, а с его дайджестом (digest), то есть «сжатым» при помощи алгоритма криптографического хеширования (например, SHA-1 или гостовского СТРИБОГ). И в целом схема выглядит так:
На практике байты цифровой подписи и байты собственно исходного (подписанного) сообщения укладываются в один файл-контейнер, но важно понимать, что в процессе верификации они разделяются. Цифровая подпись обычно достаточно короткая, порядка нескольких сотен байтов максимум.
Во многих статьях (например, здесь) можно встретить некорректное и устаревшее описание цифровой подписи, в нём она является зашифрованным с помощью закрытого ключа дайджестом, а соответственно верификация производится расшифровкой подписи с помощью открытого ключа и последующим сравнением результата с отдельно подсчитанным на стороне получателя дайджестом сообщения. Такой процесс возможен для RSA, почти во всех остальных криптосистемах шифрование собственно открытыми/закрытыми ключами принципиально не поддерживается, а поддерживается только создание цифровой подписи. Однако для организации защищённого канала этого достаточно и я ниже в разделе Используемые криптоалгоритмы подробно расскажу, как при помощи произвольного алгоритма цифровой подписи организовать безопасное шифрование и дешифрование данных. А в практическом разделе расскажу, как это сделать командами openssl.
──────────────────
В итоге, если у отправителя и получателя есть пара из собственного закрытого и открытого ключа другой стороны, они могут безопасно обмениваться сообщениями. То есть с шифрованием и аутентификацией.
приложение. требования к форме квалифицированного сертификата ключа проверки электронной подписи | гарант
Требования к форме квалифицированного сертификата ключа проверки электронной подписи
I. Общие положения
2. В настоящих Требованиях используются следующие основные понятия, определенные в статье 2 Федерального закона:
1) электронная подпись (далее – ЭП) – информация в электронной форме, которая присоединена к другой информации в электронной форме (подписываемой информации) или иным образом связана с такой информацией и которая используется для определения лица, подписывающего информацию;
2) ключ ЭП – уникальная последовательность символов, предназначенная для создания ЭП;
3) ключ проверки ЭП – уникальная последовательность символов, однозначно связанная с ключом ЭП и предназначенная для проверки подлинности ЭП (далее – проверка ЭП);
5) сертификат ключа проверки ЭП – электронный документ или документ на бумажном носителе, выданные УЦ либо доверенным лицом УЦ и подтверждающие принадлежность ключа проверки ЭП владельцу сертификата ключа проверки ЭП;
7) владелец сертификата ключа проверки ЭП – лицо, которому в установленном Федеральным законом порядке выдан сертификат ключа проверки ЭП;
9) средства ЭП – шифровальные (криптографические) средства, используемые для реализации хотя бы одной из следующих функций – создание ЭП, проверка ЭП, создание ключа ЭП и ключа проверки ЭП;
10) средства УЦ – программные и (или) аппаратные средства, используемые для реализации функций УЦ;
12) заявитель – коммерческая организация, некоммерческая организация, индивидуальный предприниматель, физическое лицо, не зарегистрированное в качестве индивидуального предпринимателя, но осуществляющее профессиональную деятельность, приносящую доход, в соответствии с федеральными законами на основании государственной регистрации и (или) лицензии, в силу членства в саморегулируемой организации, а также любое иное физическое лицо, лица, замещающие государственные должности Российской Федерации или государственные должности субъектов Российской Федерации, должностные лица государственных органов, органов местного самоуправления, работники подведомственных таким органам организаций, нотариусы и уполномоченные на совершение нотариальных действий лица, обращающиеся с соответствующим заявлением на выдачу сертификата ключа проверки ЭП в УЦ за получением сертификата ключа проверки ЭП в качестве будущего владельца такого сертификата.
3. Настоящие Требования устанавливают требования к совокупности и порядку расположения полей квалифицированного сертификата (далее – форма квалифицированного сертификата).
4. При включении в состав квалифицированного сертификата дополнительных полей требования к их назначению и расположению в квалифицированном сертификате определяются в техническом задании на разработку (модернизацию) средств УЦ.
II. Требования к совокупности полей квалифицированного сертификата
5. Требования к совокупности полей квалифицированного сертификата устанавливаются на основании Федерального закона.
6. В соответствии со статьями 14 и 17 Федерального закона квалифицированный сертификат должен содержать следующую информацию:
– уникальный номер квалифицированного сертификата;
– даты начала и окончания действия квалифицированного сертификата;
– фамилия, имя и отчество (если имеется) владельца квалифицированного сертификата – для физического лица, либо наименование и место нахождения владельца квалифицированного сертификата – для юридического лица, а также в случаях, предусмотренных Федеральным законом, фамилия, имя и отчество (если имеется) физического лица, действующего от имени владельца квалифицированного сертификата – юридического лица на основании учредительных документов юридического лица или доверенности (далее – уполномоченный представитель юридического лица);
– страховой номер индивидуального лицевого счета (далее – СНИЛС) владельца квалифицированного сертификата – для физического лица;
– основной государственный регистрационный номер (далее – ОГРН) владельца квалифицированного сертификата – для российского юридического лица;
– основной государственный регистрационный номер индивидуального предпринимателя (далее – ОГРНИП) – владельца квалифицированного сертификата – для физического лица, являющегося индивидуальным предпринимателем;
– идентификационный номер налогоплательщика (далее – ИНН) владельца квалифицированного сертификата – для физического лица, российского юридического лица и, при наличии, для иностранной организации (в том числе филиалов, представительств и иных обособленных подразделений иностранной организации);
– уникальный ключ проверки ЭП;
– наименование используемого средства ЭП и (или) стандарты, требованиям которых соответствует ключ ЭП и ключ проверки ЭП;
– наименования средств ЭП и средств аккредитованного УЦ, которые использованы для создания ключа ЭП, ключа проверки ЭП, квалифицированного сертификата, а также реквизиты документа, подтверждающего соответствие указанных средств требованиям, установленным в соответствии с Федеральным законом;
– наименование и место нахождения аккредитованного УЦ, который выдал квалифицированный сертификат;
– номер квалифицированного сертификата аккредитованного УЦ;
– идентификатор, однозначно указывающий на то, что идентификация заявителя при выдаче сертификата ключа проверки ЭП проводилась либо при его личном присутствии, либо без его личного присутствия с использованием квалифицированной ЭП при наличии действующего квалифицированного сертификата либо посредством идентификации заявителя – гражданина Российской Федерации с применением информационных технологий без его личного присутствия путем предоставления информации, указанной в документе, удостоверяющем личность гражданина Российской Федерации за пределами территории Российской Федерации, содержащем электронный носитель информации с записанными на нем персональными данными владельца паспорта, включая биометрические персональные данные, или путем предоставления сведений из федеральной государственной информационной системы “Единая система идентификации и аутентификации в инфраструктуре, обеспечивающей информационно-технологическое взаимодействие информационных систем, используемых для предоставления государственных и муниципальных услуг в электронной форме” 1 (далее – единая система идентификации и аутентификации) и единой информационной системы персональных данных, обеспечивающей обработку, включая сбор и хранение биометрических персональных данных, их проверку и передачу информации о степени их соответствия предоставленным биометрическим персональным данным гражданина Российской Федерации (далее – единая биометрическая система), в порядке, установленном Федеральным законом от 27 июля 2006 г. N 149-ФЗ “Об информации, информационных технологиях и о защите информации” 2.
------------------------------
1Постановление Правительства Российской Федерации от 28 ноября 2021 г. N 977 “О федеральной государственной информационной системе “Единая система идентификации и аутентификации в инфраструктуре, обеспечивающей информационно-технологическое взаимодействие информационных систем, используемых для предоставления государственных и муниципальных услуг в электронной форме” (Собрание законодательства Российской Федерации, 2021, N 49 (ч. V), ст. 7284; 2020, N 34, ст. 5484).
2 Собрание законодательства Российской Федерации, 2006, N 31 (ч. I), ст. 3448; 2020, N 24, ст. 3751.
------------------------------
7. Квалифицированный сертификат должен содержать квалифицированную ЭП аккредитованного УЦ (доверенного лица аккредитованного УЦ, уполномоченного федерального органа), подтверждающую принадлежность ключа проверки ЭП владельцу квалифицированного сертификата.
III. Требования к порядку расположения полей квалифицированного сертификата
10. Структура квалифицированного сертификата в форме электронного документа, определенная в соответствии со спецификацией абстрактной синтаксической нотации версии один 2, должна иметь следующий общий вид:
Certificate ::= SIGNED { SEQUENCE {version [0] Version DEFAULT v l,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueIdentifier [1] IMPLICIT UniqueIdentifier OPTIONAL,
subjectUniqueIdentifier [2] IMPLICIT UniqueIdentifier OPTIONAL,
extensions [3] Extensions OPTIONAL } }
SIGNED { ToBeSigned } ::= SEQUENCE {toBeSigned ToBeSigned,
COMPONENTS OF SIGNATURE { ToBeSigned } }SIGNATURE { ToBeSigned } ::= SEQUENCE {algorithmIdentifier AlgorithmIdentifier,
encrypted ENCRYPTED-HASH { ToBeSigned } }ENCRYPTED-HASH { ToBeSigned } ::= BIT STRING (CONSTRAINED BY { ToBeSigned }).------------------------------
2 Справочно: Спецификация абстрактной синтаксической нотации версии один определена в ГОСТ Р ИСО/МЭК 8824-1-2001 “Информационная технология. Абстрактная синтаксическая нотация версии один (АСН.1). Часть 1. Спецификация основной нотации”.
------------------------------
12. Поле encrypted содержит ЭП, сформированную аккредитованным УЦ, доверенным лицом аккредитованного УЦ либо уполномоченным федеральным органом под структурированной совокупностью полей квалифицированного сертификата (toBeSigned).
15. Поле signature (подпись) содержит идентификатор криптографического алгоритма, с использованием которого аккредитованный УЦ, доверенное лицо аккредитованного УЦ либо уполномоченный федеральный орган сформировали ЭП данного квалифицированного сертификата. Содержимое данного поля должно совпадать с содержимым поля algorithmIdentifier.
17. Стандартные атрибуты имени описаны в справочнике выбранных типов атрибутов 1. При описании формы квалифицированного сертификата используются следующие стандартные атрибуты имени:
------------------------------
1 Справочно: Выбранные типы атрибутов определены в ГОСТ Р ИСО/МЭК 9594-6-98 “Информационная технология. Взаимосвязь открытых систем. Справочник. Часть 6. Выбранные типы атрибутов” и в международном стандарте ISO/IEC 9594-6:2008 “Information technology – Open systems interconnection – The Directory: Selected attribute types”, опубликованном по адресу в информационно-телекоммуникационной сети Интернет: http://www.itu.int/rec/T-REC-X.520-200811-I/en.
------------------------------
18. К дополнительным атрибутам имени, необходимость использования которых устанавливается в соответствии с Федеральным законом, относятся:
20. Поле subject имеет тип Name и идентифицирует владельца квалифицированного сертификата.
22. Необязательные поля issuerUniqueIdentifier и subjectUniqueIdentifier имеют тип UniqueIdentifier. Настоящие Требования не устанавливают требований к использованию указанных полей.
25. Дополнение keyUsage определяет область использования ключа проверки ЭП, содержащегося в поле subjectPublicKeylnfo квалифицированного сертификата. Дополнение keyUsage имеет тип KeyUsage, структура которого определяется следующим образом:
KeyUsage ::= BIT STRING {digitalSignature (0),
contentCommitment (1),
keyEncipherment (2),
dataEncipherment (3),
keyAgreement (4),
keyCertSign (5),
cRLSign (6),
encipherOnly (7),
decipherOnly (8)}.
Значение “1” в нулевом бите означает, что область использования ключа включает проверку ЭП под электронными документами, отличными от квалифицированных сертификатов и списков уникальных номеров квалифицированных сертификатов ключей проверки ЭП, действие которых на определенный момент было прекращено УЦ до истечения их действия (далее – список аннулированных сертификатов), предназначенными для выполнения процедур аутентификации или контроля целостности.
Значение “1” в первом бите означает, что область использования ключа включает проверку ЭП под электронными документами, отличными от квалифицированных сертификатов и списков аннулированных сертификатов, в отношении которых ставится задача обеспечения невозможности отказа подписавшего лица от своего действия.
Значение “1” во втором бите означает, что область использования ключа включает зашифрование закрытых или секретных ключей, например в целях их защищенной доставки.
Значение “1” в третьем бите означает, что область использования ключа включает непосредственно зашифрование пользовательских данных без дополнительного использования методов симметричной криптографии.
Значение “1” в четвертом бите означает, что область использования ключа включает согласование ключей.
Значение “1” в пятом бите означает, что область использования ключа включает проверку подписей под квалифицированными сертификатами.
Значение “1” в шестом бите означает, что область использования ключа включает проверку подписей под списками аннулированных сертификатов.
Значение “1” в седьмом бите означает, что область использования ключа включает зашифрование данных в процессе согласования ключей (при этом в четвертом бите должно быть значение “1”).
Значение “1” в восьмом бите означает, что область использования ключа включает расшифрование данных в процессе согласования ключей (при этом в четвертом бите должно быть значение “1”).
Объектный идентификатор дополнения keyUsage имеет вид 2.5.29.15.
28. Сведения о классе средств ЭП владельца квалифицированного сертификата должны быть указаны в дополнении certificatePolicies путем включения следующих идентификаторов:
– для класса средств ЭП КС 1: 1.2.643.100.113.1,
– для класса средств ЭП КС2: 1.2.643.100.113.1, 1.2.643.100.113.2,
– для класса средств ЭП КС3: 1.2.643.100.113.1, 1.2.643.100.113.2, 1.2.643.100.113.3,
– для класса средств ЭП КВ1: 1.2.643.100.113.1, 1.2.643.100.113.2, 1.2.643.100.113.3, 1.2.643.100.113.4,
– для класса средств ЭП КВ2: 1.2.643.100.113.1, 1.2.643.100.113.2, 1.2.643.100.113.3, 1.2.643.100.113.4, 1.2.643.100.113.5,
– для класса средств ЭП КА1: 1.2.643.100.113.1, 1.2.643.100.113.2, 1.2.643.100.113.3, 1.2.643.100.113.4, 1.2.643.100.113.5, 1.2.643.100.113.6.
Для средств ЭП, класс которых отличается от класса средств УЦ, в которых используются указанные средства ЭП, следует указывать идентификаторы для класса средств ЭП, соответствующего классу средств УЦ.
28.1. Для указания в квалифицированном сертификате идентификатора, однозначно указывающего на то, что идентификация заявителя при выдаче сертификата ключа проверки ЭП проводилась при его личном присутствии или без его личного присутствия с использованием квалифицированной ЭП при наличии действующего квалифицированного сертификата либо без личного присутствия заявителя – гражданина Российской Федерации с применением информационных технологий путем предоставления информации, указанной в документе, удостоверяющем личность гражданина Российской Федерации за пределами территории Российской Федерации, содержащем электронный носитель информации с записанными на нем персональными данными владельца паспорта, включая биометрические персональные данные, или путем предоставления сведений из единой системы идентификации и аутентификации и единой биометрической системы в порядке, установленном Федеральным законом от 27 июля 2006 г. N 149-ФЗ “Об информации, информационных технологиях и о защите информации”, должно использоваться некритичное дополнение identificationKind типа IdentificationKind, имеющего следующее представление:
IdentificationKind ::= INTEGER { personal(O), remote_cert(l), remote_passport(2), remote_system(3) }.
В случае, если идентификация заявителя при выдаче сертификата ключа проверки ЭП проводилась при его личном присутствии, дополнение identificationKind должно иметь значение 0.
В случае, если идентификация заявителя при выдаче сертификата ключа проверки ЭП проводилась без его личного присутствия с использованием квалифицированной ЭП при наличии действующего квалифицированного сертификата, дополнение identificationKind должно иметь значение 1.
В случае, если идентификация заявителя – гражданина Российской Федерации при выдаче сертификата ключа проверки ЭП проводилась без его личного присутствия с применением информационных технологий путем предоставления информации, указанной в документе, удостоверяющем личность гражданина Российской Федерации за пределами территории Российской Федерации, содержащем электронный носитель информации с записанными на нем персональными данными владельца паспорта, включая биометрические персональные данные, дополнение identificationKind должно иметь значение 2.
В случае, если идентификация заявителя – гражданина Российской Федерации при выдаче сертификата ключа проверки ЭП проводилась без его личного присутствия с применением информационных технологий путем предоставления сведений из единой системы идентификации и аутентификации и единой биометрической системы в порядке, установленном Федеральным законом от 27 июля 2006 г. N 149-ФЗ “Об информации, информационных технологиях и о защите информации”, дополнение identificationKind должно иметь значение 3.
Объектный идентификатор типа IdentificationKind имеет вид 1.2.643.100.114.
29. Для указания в квалифицированном сертификате наименования используемого владельцем квалифицированного сертификата средства ЭП должно использоваться некритичное дополнение subjectSignTool типа UTF8String SIZE(1..200), объектный идентификатор которого имеет вид 1.2.643.100.111.
30. Для указания в квалифицированном сертификате наименования средств ЭП и средств аккредитованного УЦ, которые использованы для создания ключа ЭП, ключа проверки ЭП, квалифицированного сертификата, а также реквизитов документа, подтверждающего соответствие указанных средств требованиям, установленным законодательством Российской Федерации, должно использоваться некритичное дополнение issuerSignTool типа IssuerSignTool, имеющего следующее представление:
IssuerSignTool ::= SEQUENCE {signTool UTF8String SIZE(1.200),
cATool UTF8String SIZE(1..200),
signToolCert UTF8String SIZE(1.. 100),
cAToolCert UTF8String SIZE(1.100) }.
В строковом поле signTool должно содержаться полное наименование средства ЭП, которое было использовано для создания ключа ЭП, ключа проверки ЭП и квалифицированного сертификата.
В строковом поле cATool должно содержаться полное наименование средства аккредитованного УЦ, которое было использовано для создания ключа ЭП, ключа проверки ЭП и квалифицированного сертификата.
В строковом поле signToolCert должны содержаться реквизиты заключения ФСБ России о подтверждении соответствия средства ЭП, которое было использовано для создания ключа ЭП, ключа проверки ЭП, требованиям, установленным в соответствии с Федеральным законом (далее – заключение о подтверждении соответствия средства электронной подписи).
В строковом поле cAToolCert должны содержаться реквизиты заключения ФСБ России о подтверждении соответствия средства УЦ, которое было использовано для создания квалифицированного сертификата, требованиям, установленным в соответствии с Федеральным законом (далее – заключение о подтверждении соответствия средства удостоверяющего центра).
Объектный идентификатор типа IssuerSignTool имеет вид 1.2.643.100.112.
IV. Требования к форме квалифицированного сертификата
на бумажном носителе
Закрытый ключ rsa¶
Классическая команда для создания ключа RSA длиной 512 бит в файле rsa512_1.pem выглядит так:
Результатом будет файл с одним PEM-блоком с меткой RSA PRIVATE KEY:
Внутри этого блока закодирован объект в формате, описанном в стандарте PKCS#1. PKCS#1 описывает алгоритм RSA, на данный момент его актуальный текст опубликован в виде RFC 3447. В стандарте описаны бинарные структуры ключей, именно в этом формате их создаёт команда openssl genrsa.
Вот как выглядит разобранный на составные закрытый ключ RSA в формате PKCS#1 (я сократил слишком длинные строки для читабельности, помним, что почти все объекты в нашей области закодированы в DER, который позволяет проводить автоматический разбор структуры):
Для бо́льшей наглядности я использовал аргумент -i, он отделяет вложенные блоки отступом. В данном случае мы видим, что внутри файла последовательно записаны девять чисел, в RFC 3447, раздел A.1.2 даётся такое ASN.1 определение этой структуры:
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
Первое поле — версия данных, это стандартная практика, а дальше идут восемь чисел, определяющих закрытый ключ RSA. Программы, использующие закрытый ключ, разбирают эти данные на числа и дальше пользуются ими для работы.
Команда openssl genrsa не умеет записывать ключ сразу в формате DER. Если вам нужен именно он, можно сконвертировать ключ из rsa512_1.pem в файл rsa512_1.der вот такой командой:
Аргумент -outform DER как раз задаёт выходной формат данных, если его не указывать, то подразумевается -outform PEM.
──────────────────
Как я уже упоминал выше, данные закрытого ключа можно зашифровать симметричным алгоритмом. Для этого нужно в команду openssl genrsa передать дополнительный аргумент, после чего программа попросит вас ввести два раза пароль, которым будут зашифрованы сгенерённые данные. Например, чтобы зашифровать ключ шифром AES-128-CBC, нужно выполнить команду:
Результирующий файл rsa512_1_e.pem содержит один PEM-блок с такой же меткой RSA PRIVATE KEY, однако к блоку добавлены дополнительные атрибуты (они описаны в RFC 1421), указывающие, что данные внутри зашифрованы:
Расшифровать такой файл можно такой командой (нужно знать пароль, которым зашифрованы данные):
Ну и также вы можете зашифровать уже имеющийся закрытый ключ RSA (rsa512_1.pem) командой openssl rsa (воспользуемся алгоритмом AES-192-CBC):
Замечания
Список доступных алгоритмов для шифрования зависит от версии и сборки openssl. Базовые алгоритмы типа AES-128-CBC, AES-192-CBC, DES-CBC, DES-EDE3-CBC и несколько других обычно есть везде.
Как вы могли заметить, для создания ключей RSA используется команды openssl genrsa, а для модификации — openssl rsa. Вторая команда также может использоваться для конвертации PEM в DER и обратно, генерации открытого ключа из закрытого и некоторых других операций.
Зашифрованный ключ формата PKCS#1 нельзя хранить в виде DER-файла. Если вы попытаетесь сконвертировать закрытый RSA-ключ командой openssl rsa, то программа спросит у вас пароль и запишет DER-файл с расшифрованным ключом внутри.
Никогда не используйте закрытый RSA ключ длиной менее 2048 бит, я в статье использую 512 только для демонстрации!
Инфраструктура уц и сертификаты¶
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 может им подписать множество других сертификатов, вы автоматически доверяете всем им.
Естественно, бесконтрольное подписывание сертификатов ломает схему автоматического доверия, поэтому в сертификате есть специальное поле, которое разрешает или запрещает использовать этот сертификат при построении цепочки доверия. Если в вашем сертификате оно запрещает, то вы по-прежнему сможете подписать им другой сертификат, однако алгоритм верификации сразу такую цепочку «зарежет».
В итоге, только удостоверяющие центры (certification authority) обладают сертификатами, которые можно использовать для подписывания других сертификатов, чтобы они могли включаться в цепочку доверия. Их принято называть CA-сертификатами (CA certificate).
В итоге получается, что корневой сертификат лежит в основе огромного количества цепочек доверия, которые автоматически верифицируюся, если корневой сертификат находится в статусе доверенного. В любой современной операционной системе есть системное хранилище доверенных корневых сертификатов, эти сертификаты (и соответственно хранилище) меняются чрезвычайно редко и как правило это делается при обновлении операционной системы.
──────────────────
Также в сертификате есть множество других полей, которые ограничивают его применение. Например, диапазон дат, внутри которых сертификат можно считать доверенным. Практически все системы помечают сертификат недоверенным, если текущая дата в системе лежит вне указанного в сертификате диапазона.
Здесь нужно отметить, что интерпретация «срока годности» сертификата целиком лежит на стороне программного обеспечения, которое сертификат использует. Нет никаких объективных причин, по которым сертификат перестаёт быть доверенным после достижения некоторой даты.
──────────────────
Когда удостоверяющий центр выписывает сертификат, он записывает в поле serialNumber числовое значение, которое должно быть разным для каждого сертификата, заверенного этим конкретным сертификатом УЦ (X.509, п. 4.1.2.2). Туда можно записывать порядковый номер, можно текущую дату-время, можно случайное число, главное требование — это число должно быть уникальным для каждого выписанного сертификата.
──────────────────
X.509 — стандарт очень гибкий и позволяет добавлять произвольные дополнительные поля помимо базовых, это делается через расширения (extensions), я о них подробнее расскажу в практической части.
Использование сертификатов для шифрования¶
Этот раздел довольно экстремальный, поскольку описанный в нём метод мало подходит для практического применения. Однако он описывает подход, применяемый в современном TLS-шифровании веб-трафика.
В общем случае X.509-сертификаты не предназначены для шифрования данных, единственный пригодный для этого алгоритм — RSA, однако это исключение. Тем не менее, в разделе Используемые криптоалгоритмы я рассказал, как можно использовать сертификаты совместно с протоколом Diffie-Hellman для безопасного обмена ключами симметричного шифрования. А в этом разделе я расскажу, как это можно реализовать на практике через команды openssl.
Действующие лица: Алиса и Боб, у каждого из них есть свой X.509-сертификат с закрытым ключом, причём Алиса и Боб заранее обменялись сертификатами каким-то надёжным способом (например, при личной встрече). И с этого момента весь обмен данными происходит через небезопасный открытый канал.
Алиса хочет организовать безопасный сеанс связи с Бобом поверх небезопасного канала. Для этого отлично подходит симметричный алгоритм AES-128-CBC, однако для него обе стороны должны использовать одинаковый ключ — набор байтов размером 128 бит. Алиса и Боб будут для обмена ключом пользоваться протоколом Diffie-Hellman с аутентификацией через цифровые подписи.
Создадим сначала сертификаты и закрытые ключи к ним для каждой из сторон. Алиса создаёт закрытый ключ alice-x509.key и самоподписанный сертификат alice-x509.crt:
И Боб делает то же самое — ключ в файле bob-x509.key и самоподписанный сертификат bob-x509.crt:
Дальше стороны должны заранее надёжным и безопасным способом передать друг-другу свои сертификаты.
──────────────────
Через какое-то время Алиса захотела обменяться важными данными с Бобом через e-mail. Это начало новой сессии обмена, в которой будут использоваться новые ключи (эфемерные, то есть не фиксированные, а созданные специально для этого момента, после сессии эфемерные ключи стираются), поэтому Алиса должна выбрать параметры протокола Diffie-Hellman, это делается такой командой:
Здесь 4096 означает размер случайного простого числа в битах, он в настоящее время считается безопасным. Теперь Алиса на основе этого файла с параметрами создаёт свой закрытый ключ dh-alice.key (это ещё не эфемерный ключ, а только заготовка для него!):
И выделяет из него открытый ключ:
Затем Алиса конкатенирует два файла dhp.pem и alice-dh-pub.pem в один alice2bob.pem:
И создаёт цифровую подпись для него (в виде отдельного файла alice2bob.pem.sig), используя свой закрытый ключ от X.509-сертификата:
Дальше Алиса отправляет Бобу два файла: alice2bob.pem и alice2bob.pem.sig.
──────────────────
Боб получает от Алисы файл и цифровую подпись. Для проверки подписи ему сначала нужно извлечь из сертификата Алисы открытый ключ в файл alice-x509-pubkey.pem:
И дальше проверить им цифровую подпись:
Проверка прошла успешно, теперь Боб уверен, что полученный им файл alice2bob.pem действительно пришёл от Алисы, поэтому можно продолжать. Боб создаёт свой закрытый DH-ключ на основе полученных параметров:
Обратите внимание, что в аргументе с параметрами указан файл alice2bob.pem, в котором записано два разных PEM-блока, но так как PEM — это контейнер, openssl берёт из него только те данные, которые ему нужны в текущем контексте, а здесь контекст — это параметры DH, именно такой блок и будет прочитан. Другими словами, нет никакой необходимости разделять файл на части.
Дальше Боб выделяет открытый ключ на основе только что созданного закрытого:
И, наконец, создаёт свой эфемерный закрытый ключ в файле bob-secret.key:
Теперь Боб создаёт цифровую подпись для своего открытого DH-ключа:
И отправляет Алисе два файла: bob-dh-pub.pem и bob-dh-pub.pem.sig.
──────────────────
Алиса проверяет цифровую подпись аналогичным образом: выделяет открытый ключ из сертификата Боба и верифицирует файл bob-dh-pub.pem с подписью bob-dh-pub.pem.sig:
И, наконец, Алиса создаёт свой эфемерный ключ на основе собственного закрытого DH-ключа (alice-dh.key) и полученного от Боба открытого DH-ключа (bob-dh-pub.pem):
Мы можем убедиться, что оба их эфемерных ключа одинаковые:
──────────────────
Теперь Алиса может зашифровать файл alice-message.txt (внутри которого только одна строчка: Very secret message.), используя эфемерный ключ в качестве пароля:
Здесь мы используем алгоритм хеширования MD5, чтобы получить из файла эфемерного ключа ровно 128 бит AES-ключа.
Боб теперь может расшифровать файл так:
Аналогичным образом Боб может зашифровать свой текст и отправить Алисе, ключ для его расшифровки есть только у них двоих. После завершения обмена сообщениями они оба удаляют свои эфемерные ключи и для следующего сеанса создают их заново.
Используемые криптоалгоритмы¶
В инфраструктуре открытых ключей чаще всего используются 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-2021 также использует эллиптические кривые для работы. Некоторые из 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).
Ранее мы уже договорились, что контейнером для распространения открытого ключа является цифровой сертификат. И теперь остаётся вопрос: каким образом сертификат сервера оказывается у клиента перед установкой соединения.
Просмотр сертификата¶
Просмотр сертификата — это, пожалуй, самая частая операция, которую вы будете делать. Так как первый сертификат мы сделали только что, то и команда для его просмотра в этом разделе. Вот как это выглядит на примере только что созданного сертификата demo-root-ca.crt:
Аргумент -text означает, что мы хотим посмотреть представление сертификата в текстовом человекочитаемом виде, а -noout означает, что собственно содержимое сертификата в виде PEM-блока на экран выводить не нужно.
──────────────────
Структура сертификата в виде ASN.1-определения задана в RFC 5280, раздел 4.1. Basic Certificate Fields:
Если вы внимательно читали предыдущие разделы, то заметите, что структура аналогична CSR: блок данных типа TBSCertificate, идентификатор алгоритма и цифровая подпись. Вся содержательная часть сертификата находится внутри блока с типом TBSCertificate (напомню, что tbs расшифровывается как to be signed, то есть подлежит подписи или требует подписи). TBSCertificate определяется там же в RFC 5280 следующим образом:
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL
-- If present, version MUST be v3
}
Первые семь базовых полей являются обязательными, они всегда есть в любом сертификате (их семантика описана в RFC 5280, раздел 4.1.2 TBSCertificate):
- version
- версия формата сертификата, здесь может быть либо значение 0 (означает версию 1, указывается, когда в рассматриваемом блоке tbsCertificate есть только базовые поля); либо значение 2 (означает версию 3, указывается, когда есть дополнительные поля). Другие значения помимо 0 или 2 в стандарте не определены и на практике не должны использоваться.
- serialNumber
- порядковый номер сертификата в реестре УЦ, про него я писал выше, здесь должно быть число, уникальное для каждого сертификата, подписанного конкретным сертификатом УЦ.
- signature
- в этом поле указывается идентификатор алгоритма цифровой подписи, которую использовал удостоверяющий центр для подписи сертификата. Формат поля зависит от использованного алгоритма, но всегда включает в себя как минимум OID конкретного алгоритма.
- issuer
- здесь содержится имя сертификата УЦ, которым был подписан этот сертификат. Как и в случае с CSR, здесь записывается не строка, а строго структурированное значение distinguished name (DN), я о нём подробно писал в разделе Типы данных → Distinguished Name (DN).
- validity
- интервал, в течение которого сертификат может быть доверенным, состоит из двух значений: notBefore и notAfter.
- subject
- субъект сертификата, то есть та персона или организация, для которой он был выписан, формат поля — DN, такой же, как и для issuer. Также значение из этого поля принято считать названием или именем сертификата,именно оно используется для отображение в браузере, например.
- subjectPublicKeyInfo
- в этом поле записывается открытый ключ субъекта, он состоит из двух последовательных значений: идентификатора алгоритма (поле algorithm, см. Типы данных → AlgorithmIdentifier)) и собственно открытого ключа в бинарной форме (поле subjectPublicKey).
