0

В сертификате отсутствует поле sn

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

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

Описание полей сертифката

Поля сертификата можно посмотреть в его свойствах, например через IE: Свойства браузера – вкладка "Содержание" – кнопка "Сертификаты" – кнопка "Просмотр" – вкладка "Состав".

Субъект (Subject) – поле идентификации субъекта (владельца) сертификата.
Наименование субъекта, хранящееся в поле "субъект", имеет определенный формат и определяется набором именованных параметров, часть которых необязательна. Содержание поля наименования субъекта (для субъекта личность):

CN (CommonName) – наименование субъекта (владельца) сертификата, для личности это ФИО.
C (CountryName ) – наименование страны, содержит двухбуквенный код страны латинскими буквами: Россия = RU.
ST (StateOrProvinceName) – регион (область, республика) страны.
L (LocalityName) – город или населенный пункт владельца (или организации владельца) сертификата.
O (OrganizationName) – наименование организации владельца сертификата.
OU (OrganizationalUnitName ) – наименование подразделения организации.
E (Email) – адрес электронной почты.
T (Title) – должность владельца сертификата в указанной (O) организации.
DC (DomainComponent) – компонент DNS имени (адреса) владельца сертификата, указывается несколько раз, в каждом случае часть DNS пути.
S (SerialNumber) – уникальный номер владельца сертификата, например № паспорта, ИНН и т.п. либо произвольный номер присвоенный владельцу УЦ.
SN (SurName) – Фамилия .
G (GivenName) – Имя и отчество.
Pseudonym – псевдоним владельца сертификата. Не используется, если заполнен параметр CN.

Пример поля "Субъект":

CN = Измаилов Синап Альпиевич

Поставщик (issuer) – поле идентификации УЦ, выдавшего сертификат владельцу.

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

Дополнительное имя субъекта (SubjectAltName) – дполнительные реквизиты владельца сертификата .
Используется для определения дополнительных субъектов, охватываемых действием данного сертификата, либо дополнительных реквизитов субъекта. Содержание поля :

«Коллеги, нам необходимо вести реестр выданных квалифицированных сертификатов с возможностью поиска по ИНН, СНИЛС и ОГРН. Сколько дней нужно для создания парсера сертификатов и первого макета?» — с такого вопроса начальника началась очередная летучка.

Поскольку написанием парсера было предложено заняться мне, пришлось задуматься и покопаться в памяти, чтобы оценить трудоемкость задачи и примерные сроки на ее выполнение.

Когда-то я участвовал в небольшом проекте по моделированию SSL MITM, где отвечал за генерацию ключей и сертификатов для этого самого «человека посередине». Поэтому представлял, что квалифицированный сертификат ключа проверки электронной подписи (далее — квалифицированный сертификат) — это сертификат X.509, для описания внутренней структуры которого используется всеми любимый ASN.1.

Вот только не помнил я, чтобы тогда на глаза попадались эти ИННы, СНИЛСы и ОГРНы. Поэтому ответил более, чем скромно: «Босс, два дня, не меньше!», надеясь выполнить задачку за несколько часов.

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

Шаг 1. Предварительные изыскания и проверка гипотезы

Нет, серьезно, это правда, что в сертификате X.509 есть СНИЛС? Для проверки найдем образец — просим помощи у Яндекса по запросу «реестр выданных квалифицированных сертификатов», на первой же странице выдачи находим Реестр выданных УЦ ГКУ ЛО «ОЭП» сертификатов, скачиваем первый попавшийся сертификат (под номером 10842) — Komarov_Aleksey_Petrovich_2017-03-31_a2ba20c4.cer.

Открываем сертификат с помощью стандартного средства просмотра OC Windows и находим в описании субъекта подозрительно похожую строку с объектным идентификатором 1.2.643.100.3, состоящую из 11 цифр. СНИЛС?

О том, что такое объектный идентификатор (OID) вообще, лучше всего почитать здесь. Как используются объектные идентификаторы в описании структуры сертификатов X.509 — смотрим Руководство по выживанию — TLS/SSL и сертификаты SSL (X.509).

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

Итак, поставленная задача потенциально выполнима, СНИЛС в квалифицированном сертификате есть. Идем дальше.

Шаг 2. Знакомство с нормативной базой

Естественно, не в любом сертификате X.509 можно найти ИНН, СНИЛС и ОГРН. К примеру, если в браузере щелкнуть по замочку рядом с адресной строкой «https://yandex.ru/» и экспортировать сертификат, то там никаких длинных цифровых последовательностей не обнаружится.

При этом следует заметить, что стандарт Х.509 не ограничивает набор атрибутов, которые могут быть указаны в имени издателя и/или субъекта. Стандарт лишь рекомендует поддерживать ряд атрибутов, среди которых — страна, организация, регион, общепринятое имя и др., но о СНИЛСе и прочем не сказано ни слова.

Интересующие нас данные точно содержатся в сертификатах, которые попадают в сферу действия Федерального закона «Об электронной подписи» от 06 апреля 2011 г. № 63-ФЗ. Внимательно изучаем статью 17 и убеждаемся, что ИНН, СНИЛС и ОГРН действительно должны содержаться в квалифицированных сертификатах.

Читайте также:  Где двойные кавычки на клавиатуре

Теперь необходимо узнать, какой OID соответствует значению ИНН, а какой — СНИЛС и ОГРН. С этим вопросом поможет обзор нормативной базы, где упоминается Приказ ФСБ РФ от 27 декабря 2011 г. № 795 «Об утверждении требований к форме квалифицированного сертификата. ». Открываем приказ и находим интересующую нас информацию:

18. К дополнительным атрибутам имени, необходимость использования которых устанавливается в соответствии с Федеральным законом, относятся:

1) OGRN (ОГРН).
Значением атрибута OGRN является строка, состоящая из 13 цифр и представляющая ОГРН владельца квалифицированного сертификата — юридического лица. Объектный идентификатор типа атрибута OGRN имеет вид 1.2.643.100.1, тип атрибута OGRN описывается следующим образом: OGRN ::= NUMERIC STRING SIZE 13;

2) SNILS (СНИЛС).
Значением атрибута SNILS является строка, состоящая из 11 цифр и представляющая СНИЛС владельца квалифицированного сертификата — физического лица. Объектный идентификатор типа атрибута SNILS имеет вид 1.2.643.100.3, тип атрибута SNILS описывается следующим образом: SNILS ::= NUMERIC STRING SIZE 11;

3) INN (ИНН).
Значением атрибута INN является строка, состоящая из 12 цифр и представляющая ИНН владельца квалифицированного сертификата. Объектный идентификатор типа атрибута INN имеет вид 1.2.643.3.131.1.1, тип атрибута INN описывается следующим образом: INN ::= NUMERIC STRING SIZE 12.

Можно попробовать проверить себя — зная O >

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

Проверить себя не получится, поскольку не все ярусы отображены на сайте национального реестра объектных идентификаторов. Но надежда умирает последней, пробуем отправить официальный запрос оператору национального дерева – в ОАО «Инфотекс Интернет Траст». Цитируем переписку:

– Подскажите, возможно ли на сайте oid.iitrust.ru уточнить, каким объектам соответствуют OID’ы: 1.2.643.3.131.1.1, 1.2.643.100.1, 1.2.643.100.3? В поиске они не находятся, но мы предполагаем, что это ИНН, ОГРН и СНИЛС. Как можно получить подтверждение этому?

– День добрый! Указанные Вами OID утверждены приказом № 795 ФСБ России от 27.12.2011.

Круг замкнулся, считаем, что проверка проведена успешно.

Продолжаем изучать Приказ ФСБ РФ от 27 декабря 2011 г. № 795 и обращаем внимание на то, что заполнение полей и их атрибутов зависит от владельца квалифицированного сертификата — физического или юридического лица. К примеру, описание заполнения атрибута commonName (общее имя):

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

В нашем случае (Komarov_Aleksey_Petrovich_2017-03-31_a2ba20c4.cer) значением атрибута commonName является строка «Комитет по природным ресурсам Ленинградской области», следовательно, владелец сертификата – юридическое лицо.

Для юридического лица устанавливаем следующее соответствие объектных идентификаторов (не всех, выборочно, интересных нам) типам атрибутов:

Шаг 3. Разработка парсера X.509 сертификата на С#

Так сложилось, что разработка у нас ведется на C#, поэтому и пример парсера будет на C#, ничего личного и никакого холивара.

Для простоты формализуем задачу следующим образом. Дано: файл квалифицированного сертификата в системе ограничений CER (Canonical encoding rules). Требуется: разобрать (распарсить) сертификат и извлечь значения ИНН, СНИЛС и ОГРН из поля субъекта (Subject).

Для первых набросков обращаемся к возможностям пространства имен System.Security.Cryptography.X509Certificates:

На выходе получаем:

Свойство X509Certificate.Subject возвращает имя субъекта сертификата с типом string.

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

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

StackOverflow даёт подсказку — использовать сторонние библиотеки, выбираем наиболее цитируемую — BouncyCastle.

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

Открываем сертификат в редакторе ASN.1 Editor и устанавливаем соответствие со структурой сертификата:

Нас интересует поле «Имя субъекта», в котором и записываются значения ИНН, СНИЛС и ОГРН. Если внимательно посмотреть на рисунок, можно сделать следующий вывод: поле «Имя субъекта» (325, 654) SEQUENCE представляет собой последовательность (SEQUENCE) множеств (SET), состоящих из последовательностей (SEQUENCE) пар ключ/значение.

В соответствии с этой логикой реализуем парсер:

Смотрим вывод, соглашаемся:

Подведение итогов

Итак, подытоживая проделанную работу, мы:

  1. Разобрались со структурой квалифицированных сертификатов X.509, которые попадают в сферу действия ФЗ «Об электронной подписи».
  2. Узнали, что Приказ ФСБ РФ № 795 определяет дополнительные атрибуты — ИНН, СНИЛС, ОГРН и другие. Здесь же указываются соответствующие объектные идентификаторы (OID).
  3. Разработали парсер сертификатов X.509 на C# с возможностью извлечения полей и их атрибутов с заданными объектными идентификаторами. Библиотека BouncyCastle добавила решению простоты.

В расчетах по времени произошла ошибка — вместо запланированных нескольких часов пришлось разбираться весь день. И еще два дня на подготовку исследования для Хабра.

Читайте также:  Как включить uefi в биосе gigabyte

Спасибо за внимание!

Список источников

Читают сейчас

Похожие публикации

  • 18 февраля 2019 в 17:25

Англоязычная кроссплатформенная утилита для просмотра российских квалифицированных сертификатов x509

Инфраструктура открытых ключей. Цепочка корневых сертификатов X509 v.3

Разбираем x.509 сертификат

Заказы

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Комментарии 16

У того самого asn1 editor, которым вы пользовались для просмотра сертификата есть обычный шарповый метод

А ещё можно обойтись коробочными решениями, там есть всё, чтобы прочитать сертификатподпись целиком.

Согласен, альтернативных решений может быть много. BouncyCastle выбран по понятной причине — чаще попадался на StackOverflow во время погружения в задачу, при этом простые примеры нужного нам обхода дерева после нескольких попыток так и не обнаружились.

Одна из идей третьей части (разработка парсера) — показать, что базовыми средствами .NET не очень удобно (читай, просто и логично) «прогуливаться» по дереву в поисках нужного OID’а.

Если честно, «сложного тут вообще» было немного: "… вместо запланированных нескольких часов пришлось разбираться весь день. И еще два дня на подготовку исследования для Хабра."

Статья писалась с простой целью — сэкономить время другим читателям Хабра на тот случай, если они столкнутся с подобной задачей (и я надеюсь, поисковики начнут выдавать этот пост для тех, кто ищет «парсинг сертификатов x.509 с#», рядом с публикацией Разбираем x.509 сертификат как хорошее дополнение). Так что, позвольте считать время, потраченное на поиск решения, показателем сложности.

Это конечно, когда уже во всем разобрался, все кажется логичным и понятным. Но когда только начинаешь погружаться в криптографию, то понимаешь, что это ЖОПА. Ведь как думаешь в начале? Да что там, ведь столько компаний вбухивают бабла в нее, такой хайп стоит, "нескольких часов хватит", чтобы разобраться.

На деле же криптография — это какая-то секта избранных. Во-первых, очень сложно понять, с чего начать, где тот якорь, с которого начать раскрутку. Пресловутые несколько часов могут уйти только на его поиски. Во-вторых, вольные трактовки понятий. Подите с первого раза разберитесь, почему описание сертификата из RFC 5280 (структура Certificate) не соответствует тому, что лежит в файлах. Ответ — потому что там лежит структура контейнера, внутри которого и находится структура Certificate, и весь этот контейнер тоже почему-то называется сертификатом. Обычно это структура PKCS#7 и описана она в RFC 2315 (и то, еще нужно догадаться, что в файле именно она, RFC же только формат описывает. Помочь разобраться в этом могут парсеры ASN.1, о них ниже), а ведь есть еще PKCS#12 и, как вы догадываетесь, пропущенные номера также не пустуют. Разобраться во всех этих хитросплетениях без подготовки крайне тяжело. Номера RFC-шек между собой если и связаны, то явно эта связь для мозга, функционирующего отлично от человеческого.

Пикантности ситуации добавляет тот факт, что, например в джаве, стандартным криптографическим API от Sun-овского криптопровайдера файл с сертификатом не прочитать, т.к. API требует именно структуру Certificate на входе, а вот BouncyCastle тут дает поблажку и может сам выпарсить ее из контейнера. Что на мой взгляд плохо, т.к. заставляет полагаться на неочевидное и негарантированное поведение конкретного криптопровайдера. И вот представьте, хотите вы структурировать для себя информацию, делаете демо пример, и с одним провайдером он работает, а с другим нет! И вот сиди думай, где тут ошибки — у тебя или в одной из библиотек, а если в библиотеке, то в какой именно и что гуглить.

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

Еще пару часов рыскаешь по гуглу, проникаешься разрухой. Хорошо, если к этому моменту удастся уже выйти на RFC (еще поди пойми, которое из них сейчас актуально!) с описанием всей этой криптографической мишуры. На этом этапе уже понимаешь, что BouncyCastle, в общем то, неплох — разбор ASN.1 структур там сделан неплохо. Собственно, пожалуй, только этим и можно нормально пользоваться, даже без документации, ее вышеприведенные RFC заменяет.

Автор в итоге и пришел к такому решению — используем хорошую часть библиотеки, забиваем на непонятную. Фактически при разборе сертификата нужно знать только его структуру, а она в RFC описана. Дальше только с помощью классов библиотеки парсим структуру и вытаскиваем нужное.

Ну и еще хотелось бы предостеречь читателей от статьи ASN.1 простыми словами (кодирование типа REAL). На мой взгляд, там не только простые слова, а героическое возведение и штурм укреплений, когда можно было пройти через ворота. Лучше ее не читать, только каши в голове добавит.

Да, и еще не могу не упомянуть замечательный сайт https://lapo.it/asn1js/ (у него есть и автономный режим работы — скачиваете html-ку) для декодирования ASN.1. Можно как вставлять как base64 так и hex, пробелы выкусываются автоматически

Только вот примерно все, описанное в топике, к криптографии не имеет ни малейшего отношения. Просто есть некий файл в ASN1/DER, который надо разобрать, понять, что внутри дерево, пройтись по нему и найти там нужное. Вместо ASN1 мог быть RIFF, TIFF, EBML, BSON, Protobuf, Apache Avro и т.д. — в общем, любой бинарный контейнер. Радикально ничего от этого не меняется.

Вместо ASN1 мог быть RIFF, TIFF, EBML, BSON, Protobuf, Apache Avro и т.д. — в общем, любой бинарный контейнер. Радикально ничего от этого не меняется.

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

Читайте также:  Изменить ip адрес на российский

Впрочем, соглашусь, что к академической криптографии описанное в посте действительно никак не относится. В академической криптографии вообще никаких контейнеров нет. Однако мы все же говорим о практическом применении. И форматы файлов — это тоже часть практической криптографии. Можете назвать еще хоть одну массовую, не нишевую, область, где ASN.1 используется? Сомневаюсь. Так что с практической точки зрения работа с ASN.1 почти равно криптографии. Или даже так: работа с ASN.1 почти всегда подразумевает касание криптографии.

Вместо ASN1 мог быть RIFF, TIFF, EBML, BSON, Protobuf, Apache Avro и т.д. — в общем, любой бинарный контейнер.

Это не совсем так. Скажем, если вы захотите сгенерировать подпись с помощью какой-то железки, которой на вход подают массив байт и ид. ключа в этой железке, а на выходе зашифрованный приватной частью этого ключа массив этих байт, то что вы будите делать? Если вы наивно полагаете, что достаточно будет запихать в нее те данные, что вы хотите подписать и получившийся массив записать в "любой бинарный контейнер", то вы заблуждаетесь. Потому, что по RFC для вычисления подписи шифруется не ваш массив, и даже не хеш от него, а хеш от ASN.1 контейнера специального вида, куда засунут хеш от вашего массива + описание алгоритма взятия хеша, параметры этого алгоритма и еще может быть чего. И шифруется уже этот контейнер, преобразованный в массив байт вполне конкретным способом.

Можете назвать еще хоть одну массовую, не нишевую, область, где ASN.1 используется?

Я могу назвать с десяток (вроде LDAP, SNMP, H.323, UMTS, LTE, WiMAX, 3GPP и вообще очень много всего в том, что касается телекомов и вокруг них), но вы удобно скажете, что это все "нишевые области". Впрочем, чем тогда "криптография" не нишевая?

Или даже так: работа с ASN.1 почти всегда подразумевает касание криптографии.

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

И вот в посте ровно пример того, где работа с ASN.1 ну совсем никак не связана с использованием криптографии. Ничего не шифруется или подписывается с целью сокрытия содержания или защиты от изменений. Сертификат используется просто как источник данных. Если бы эти данные можно было получить, обратившись в какую-нибудь БД или веб-сервис — скорее всего так бы и сделали, а не разбирали сертификаты.

Телеком — это именно что нишевая область. Криптография не нишевая, потому что это чисто утилитарная область, само по себе она никому не сдалась, нужна только вместе с чем-то. И областей, требующих для себя криптографии, вполне много.

И вот в посте ровно пример того, где работа с ASN.1 ну совсем никак не связана с использованием криптографии

Ну да, ничего не шифруется и не проверяется. Согласен. Однако работать с ASN.1 приходится под соусом криптографии. Даже парсер ASN.1 является частью криптографической библиотеки, а не отдельной библиотекой. Потому что там он не абстрактный парсер контейнеров с информацией, а все-таки наделяет эти контейнеры каким-то смыслом. Вот здесь у нас ContentInfo , здесь SignedData , а здесь EnvelopedData . Это уже часть криптографической библиотеки. Можно эти структуры считать "средствами… преобразования информации" из приведенного вами определения?

Когда занимался такими же задачами, то вместо ASN1 Editor использовал asn1js. Который отлично работает со строками. В ASN1 есть несколько типов строк, и ASN1 Editor кириллицу отображает плохо. А доработать код на C++ для поддержки Unicode не так-то просто.

И сделал пару доработок для asn1js, чтобы отображать СНИЛС, ИНН,… и иметь удобный способ сравнивать сертификаты/подписи.

К комитам есть скриншоты, посмотрите, может пригодится:

print description — классная фича, жалко, что похоже автор pull request-ы почему-то не принимает, но отослать все равно надо бы

Главная > Документ

Информация о документе
Дата добавления:
Размер:
Доступные форматы для скачивания:

Приложение № 12

к Регламенту Удостоверяющего центра Федерального казначейства,

утвержденному приказом Федерального казначейства от ___.___.2013 №_____

Формат и структура сертификата ключа подписи

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

Сертификат ключа проверки электронной подписи в электронной форме представляет собой электронный документ, имеющий структуру, соответствующую стандарту Международного союза телекоммуникаций ITU-T X.509 версии 3 и рекомендаций IETF (Internet Engineering Task Force) RFC 3280 и 5280 и представленный в кодировке Base64.

Структура сертификатов ключей подписи, изготавливаемых УЦ, определяется следующей таблицей:

admin

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

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

0

В сертификате отсутствует поле sn

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

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

Описание полей сертифката

Поля сертификата можно посмотреть в его свойствах, например через IE: Свойства браузера – вкладка "Содержание" – кнопка "Сертификаты" – кнопка "Просмотр" – вкладка "Состав".

Субъект (Subject) – поле идентификации субъекта (владельца) сертификата.
Наименование субъекта, хранящееся в поле "субъект", имеет определенный формат и определяется набором именованных параметров, часть которых необязательна. Содержание поля наименования субъекта (для субъекта личность):

CN (CommonName) – наименование субъекта (владельца) сертификата, для личности это ФИО.
C (CountryName ) – наименование страны, содержит двухбуквенный код страны латинскими буквами: Россия = RU.
ST (StateOrProvinceName) – регион (область, республика) страны.
L (LocalityName) – город или населенный пункт владельца (или организации владельца) сертификата.
O (OrganizationName) – наименование организации владельца сертификата.
OU (OrganizationalUnitName ) – наименование подразделения организации.
E (Email) – адрес электронной почты.
T (Title) – должность владельца сертификата в указанной (O) организации.
DC (DomainComponent) – компонент DNS имени (адреса) владельца сертификата, указывается несколько раз, в каждом случае часть DNS пути.
S (SerialNumber) – уникальный номер владельца сертификата, например № паспорта, ИНН и т.п. либо произвольный номер присвоенный владельцу УЦ.
SN (SurName) – Фамилия .
G (GivenName) – Имя и отчество.
Pseudonym – псевдоним владельца сертификата. Не используется, если заполнен параметр CN.

Пример поля "Субъект":

CN = Измаилов Синап Альпиевич

Поставщик (issuer) – поле идентификации УЦ, выдавшего сертификат владельцу.

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

Дополнительное имя субъекта (SubjectAltName) – дполнительные реквизиты владельца сертификата .
Используется для определения дополнительных субъектов, охватываемых действием данного сертификата, либо дополнительных реквизитов субъекта. Содержание поля :

«Коллеги, нам необходимо вести реестр выданных квалифицированных сертификатов с возможностью поиска по ИНН, СНИЛС и ОГРН. Сколько дней нужно для создания парсера сертификатов и первого макета?» — с такого вопроса начальника началась очередная летучка.

Поскольку написанием парсера было предложено заняться мне, пришлось задуматься и покопаться в памяти, чтобы оценить трудоемкость задачи и примерные сроки на ее выполнение.

Когда-то я участвовал в небольшом проекте по моделированию SSL MITM, где отвечал за генерацию ключей и сертификатов для этого самого «человека посередине». Поэтому представлял, что квалифицированный сертификат ключа проверки электронной подписи (далее — квалифицированный сертификат) — это сертификат X.509, для описания внутренней структуры которого используется всеми любимый ASN.1.

Вот только не помнил я, чтобы тогда на глаза попадались эти ИННы, СНИЛСы и ОГРНы. Поэтому ответил более, чем скромно: «Босс, два дня, не меньше!», надеясь выполнить задачку за несколько часов.

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

Шаг 1. Предварительные изыскания и проверка гипотезы

Нет, серьезно, это правда, что в сертификате X.509 есть СНИЛС? Для проверки найдем образец — просим помощи у Яндекса по запросу «реестр выданных квалифицированных сертификатов», на первой же странице выдачи находим Реестр выданных УЦ ГКУ ЛО «ОЭП» сертификатов, скачиваем первый попавшийся сертификат (под номером 10842) — Komarov_Aleksey_Petrovich_2017-03-31_a2ba20c4.cer.

Открываем сертификат с помощью стандартного средства просмотра OC Windows и находим в описании субъекта подозрительно похожую строку с объектным идентификатором 1.2.643.100.3, состоящую из 11 цифр. СНИЛС?

О том, что такое объектный идентификатор (OID) вообще, лучше всего почитать здесь. Как используются объектные идентификаторы в описании структуры сертификатов X.509 — смотрим Руководство по выживанию — TLS/SSL и сертификаты SSL (X.509).

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

Итак, поставленная задача потенциально выполнима, СНИЛС в квалифицированном сертификате есть. Идем дальше.

Шаг 2. Знакомство с нормативной базой

Естественно, не в любом сертификате X.509 можно найти ИНН, СНИЛС и ОГРН. К примеру, если в браузере щелкнуть по замочку рядом с адресной строкой «https://yandex.ru/» и экспортировать сертификат, то там никаких длинных цифровых последовательностей не обнаружится.

При этом следует заметить, что стандарт Х.509 не ограничивает набор атрибутов, которые могут быть указаны в имени издателя и/или субъекта. Стандарт лишь рекомендует поддерживать ряд атрибутов, среди которых — страна, организация, регион, общепринятое имя и др., но о СНИЛСе и прочем не сказано ни слова.

Интересующие нас данные точно содержатся в сертификатах, которые попадают в сферу действия Федерального закона «Об электронной подписи» от 06 апреля 2011 г. № 63-ФЗ. Внимательно изучаем статью 17 и убеждаемся, что ИНН, СНИЛС и ОГРН действительно должны содержаться в квалифицированных сертификатах.

Читайте также:  Вай фай адаптер для телевизора сони бравиа

Теперь необходимо узнать, какой OID соответствует значению ИНН, а какой — СНИЛС и ОГРН. С этим вопросом поможет обзор нормативной базы, где упоминается Приказ ФСБ РФ от 27 декабря 2011 г. № 795 «Об утверждении требований к форме квалифицированного сертификата. ». Открываем приказ и находим интересующую нас информацию:

18. К дополнительным атрибутам имени, необходимость использования которых устанавливается в соответствии с Федеральным законом, относятся:

1) OGRN (ОГРН).
Значением атрибута OGRN является строка, состоящая из 13 цифр и представляющая ОГРН владельца квалифицированного сертификата — юридического лица. Объектный идентификатор типа атрибута OGRN имеет вид 1.2.643.100.1, тип атрибута OGRN описывается следующим образом: OGRN ::= NUMERIC STRING SIZE 13;

2) SNILS (СНИЛС).
Значением атрибута SNILS является строка, состоящая из 11 цифр и представляющая СНИЛС владельца квалифицированного сертификата — физического лица. Объектный идентификатор типа атрибута SNILS имеет вид 1.2.643.100.3, тип атрибута SNILS описывается следующим образом: SNILS ::= NUMERIC STRING SIZE 11;

3) INN (ИНН).
Значением атрибута INN является строка, состоящая из 12 цифр и представляющая ИНН владельца квалифицированного сертификата. Объектный идентификатор типа атрибута INN имеет вид 1.2.643.3.131.1.1, тип атрибута INN описывается следующим образом: INN ::= NUMERIC STRING SIZE 12.

Можно попробовать проверить себя — зная O >

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

Проверить себя не получится, поскольку не все ярусы отображены на сайте национального реестра объектных идентификаторов. Но надежда умирает последней, пробуем отправить официальный запрос оператору национального дерева – в ОАО «Инфотекс Интернет Траст». Цитируем переписку:

– Подскажите, возможно ли на сайте oid.iitrust.ru уточнить, каким объектам соответствуют OID’ы: 1.2.643.3.131.1.1, 1.2.643.100.1, 1.2.643.100.3? В поиске они не находятся, но мы предполагаем, что это ИНН, ОГРН и СНИЛС. Как можно получить подтверждение этому?

– День добрый! Указанные Вами OID утверждены приказом № 795 ФСБ России от 27.12.2011.

Круг замкнулся, считаем, что проверка проведена успешно.

Продолжаем изучать Приказ ФСБ РФ от 27 декабря 2011 г. № 795 и обращаем внимание на то, что заполнение полей и их атрибутов зависит от владельца квалифицированного сертификата — физического или юридического лица. К примеру, описание заполнения атрибута commonName (общее имя):

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

В нашем случае (Komarov_Aleksey_Petrovich_2017-03-31_a2ba20c4.cer) значением атрибута commonName является строка «Комитет по природным ресурсам Ленинградской области», следовательно, владелец сертификата – юридическое лицо.

Для юридического лица устанавливаем следующее соответствие объектных идентификаторов (не всех, выборочно, интересных нам) типам атрибутов:

Шаг 3. Разработка парсера X.509 сертификата на С#

Так сложилось, что разработка у нас ведется на C#, поэтому и пример парсера будет на C#, ничего личного и никакого холивара.

Для простоты формализуем задачу следующим образом. Дано: файл квалифицированного сертификата в системе ограничений CER (Canonical encoding rules). Требуется: разобрать (распарсить) сертификат и извлечь значения ИНН, СНИЛС и ОГРН из поля субъекта (Subject).

Для первых набросков обращаемся к возможностям пространства имен System.Security.Cryptography.X509Certificates:

На выходе получаем:

Свойство X509Certificate.Subject возвращает имя субъекта сертификата с типом string.

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

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

StackOverflow даёт подсказку — использовать сторонние библиотеки, выбираем наиболее цитируемую — BouncyCastle.

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

Открываем сертификат в редакторе ASN.1 Editor и устанавливаем соответствие со структурой сертификата:

Нас интересует поле «Имя субъекта», в котором и записываются значения ИНН, СНИЛС и ОГРН. Если внимательно посмотреть на рисунок, можно сделать следующий вывод: поле «Имя субъекта» (325, 654) SEQUENCE представляет собой последовательность (SEQUENCE) множеств (SET), состоящих из последовательностей (SEQUENCE) пар ключ/значение.

В соответствии с этой логикой реализуем парсер:

Смотрим вывод, соглашаемся:

Подведение итогов

Итак, подытоживая проделанную работу, мы:

  1. Разобрались со структурой квалифицированных сертификатов X.509, которые попадают в сферу действия ФЗ «Об электронной подписи».
  2. Узнали, что Приказ ФСБ РФ № 795 определяет дополнительные атрибуты — ИНН, СНИЛС, ОГРН и другие. Здесь же указываются соответствующие объектные идентификаторы (OID).
  3. Разработали парсер сертификатов X.509 на C# с возможностью извлечения полей и их атрибутов с заданными объектными идентификаторами. Библиотека BouncyCastle добавила решению простоты.

В расчетах по времени произошла ошибка — вместо запланированных нескольких часов пришлось разбираться весь день. И еще два дня на подготовку исследования для Хабра.

Читайте также:  Где двойные кавычки на клавиатуре

Спасибо за внимание!

Список источников

Читают сейчас

Похожие публикации

  • 18 февраля 2019 в 17:25

Англоязычная кроссплатформенная утилита для просмотра российских квалифицированных сертификатов x509

Инфраструктура открытых ключей. Цепочка корневых сертификатов X509 v.3

Разбираем x.509 сертификат

Заказы

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Комментарии 16

У того самого asn1 editor, которым вы пользовались для просмотра сертификата есть обычный шарповый метод

А ещё можно обойтись коробочными решениями, там есть всё, чтобы прочитать сертификатподпись целиком.

Согласен, альтернативных решений может быть много. BouncyCastle выбран по понятной причине — чаще попадался на StackOverflow во время погружения в задачу, при этом простые примеры нужного нам обхода дерева после нескольких попыток так и не обнаружились.

Одна из идей третьей части (разработка парсера) — показать, что базовыми средствами .NET не очень удобно (читай, просто и логично) «прогуливаться» по дереву в поисках нужного OID’а.

Если честно, «сложного тут вообще» было немного: "… вместо запланированных нескольких часов пришлось разбираться весь день. И еще два дня на подготовку исследования для Хабра."

Статья писалась с простой целью — сэкономить время другим читателям Хабра на тот случай, если они столкнутся с подобной задачей (и я надеюсь, поисковики начнут выдавать этот пост для тех, кто ищет «парсинг сертификатов x.509 с#», рядом с публикацией Разбираем x.509 сертификат как хорошее дополнение). Так что, позвольте считать время, потраченное на поиск решения, показателем сложности.

Это конечно, когда уже во всем разобрался, все кажется логичным и понятным. Но когда только начинаешь погружаться в криптографию, то понимаешь, что это ЖОПА. Ведь как думаешь в начале? Да что там, ведь столько компаний вбухивают бабла в нее, такой хайп стоит, "нескольких часов хватит", чтобы разобраться.

На деле же криптография — это какая-то секта избранных. Во-первых, очень сложно понять, с чего начать, где тот якорь, с которого начать раскрутку. Пресловутые несколько часов могут уйти только на его поиски. Во-вторых, вольные трактовки понятий. Подите с первого раза разберитесь, почему описание сертификата из RFC 5280 (структура Certificate) не соответствует тому, что лежит в файлах. Ответ — потому что там лежит структура контейнера, внутри которого и находится структура Certificate, и весь этот контейнер тоже почему-то называется сертификатом. Обычно это структура PKCS#7 и описана она в RFC 2315 (и то, еще нужно догадаться, что в файле именно она, RFC же только формат описывает. Помочь разобраться в этом могут парсеры ASN.1, о них ниже), а ведь есть еще PKCS#12 и, как вы догадываетесь, пропущенные номера также не пустуют. Разобраться во всех этих хитросплетениях без подготовки крайне тяжело. Номера RFC-шек между собой если и связаны, то явно эта связь для мозга, функционирующего отлично от человеческого.

Пикантности ситуации добавляет тот факт, что, например в джаве, стандартным криптографическим API от Sun-овского криптопровайдера файл с сертификатом не прочитать, т.к. API требует именно структуру Certificate на входе, а вот BouncyCastle тут дает поблажку и может сам выпарсить ее из контейнера. Что на мой взгляд плохо, т.к. заставляет полагаться на неочевидное и негарантированное поведение конкретного криптопровайдера. И вот представьте, хотите вы структурировать для себя информацию, делаете демо пример, и с одним провайдером он работает, а с другим нет! И вот сиди думай, где тут ошибки — у тебя или в одной из библиотек, а если в библиотеке, то в какой именно и что гуглить.

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

Еще пару часов рыскаешь по гуглу, проникаешься разрухой. Хорошо, если к этому моменту удастся уже выйти на RFC (еще поди пойми, которое из них сейчас актуально!) с описанием всей этой криптографической мишуры. На этом этапе уже понимаешь, что BouncyCastle, в общем то, неплох — разбор ASN.1 структур там сделан неплохо. Собственно, пожалуй, только этим и можно нормально пользоваться, даже без документации, ее вышеприведенные RFC заменяет.

Автор в итоге и пришел к такому решению — используем хорошую часть библиотеки, забиваем на непонятную. Фактически при разборе сертификата нужно знать только его структуру, а она в RFC описана. Дальше только с помощью классов библиотеки парсим структуру и вытаскиваем нужное.

Ну и еще хотелось бы предостеречь читателей от статьи ASN.1 простыми словами (кодирование типа REAL). На мой взгляд, там не только простые слова, а героическое возведение и штурм укреплений, когда можно было пройти через ворота. Лучше ее не читать, только каши в голове добавит.

Да, и еще не могу не упомянуть замечательный сайт https://lapo.it/asn1js/ (у него есть и автономный режим работы — скачиваете html-ку) для декодирования ASN.1. Можно как вставлять как base64 так и hex, пробелы выкусываются автоматически

Только вот примерно все, описанное в топике, к криптографии не имеет ни малейшего отношения. Просто есть некий файл в ASN1/DER, который надо разобрать, понять, что внутри дерево, пройтись по нему и найти там нужное. Вместо ASN1 мог быть RIFF, TIFF, EBML, BSON, Protobuf, Apache Avro и т.д. — в общем, любой бинарный контейнер. Радикально ничего от этого не меняется.

Вместо ASN1 мог быть RIFF, TIFF, EBML, BSON, Protobuf, Apache Avro и т.д. — в общем, любой бинарный контейнер. Радикально ничего от этого не меняется.

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

Читайте также:  Действующие купоны на алиэкспресс

Впрочем, соглашусь, что к академической криптографии описанное в посте действительно никак не относится. В академической криптографии вообще никаких контейнеров нет. Однако мы все же говорим о практическом применении. И форматы файлов — это тоже часть практической криптографии. Можете назвать еще хоть одну массовую, не нишевую, область, где ASN.1 используется? Сомневаюсь. Так что с практической точки зрения работа с ASN.1 почти равно криптографии. Или даже так: работа с ASN.1 почти всегда подразумевает касание криптографии.

Вместо ASN1 мог быть RIFF, TIFF, EBML, BSON, Protobuf, Apache Avro и т.д. — в общем, любой бинарный контейнер.

Это не совсем так. Скажем, если вы захотите сгенерировать подпись с помощью какой-то железки, которой на вход подают массив байт и ид. ключа в этой железке, а на выходе зашифрованный приватной частью этого ключа массив этих байт, то что вы будите делать? Если вы наивно полагаете, что достаточно будет запихать в нее те данные, что вы хотите подписать и получившийся массив записать в "любой бинарный контейнер", то вы заблуждаетесь. Потому, что по RFC для вычисления подписи шифруется не ваш массив, и даже не хеш от него, а хеш от ASN.1 контейнера специального вида, куда засунут хеш от вашего массива + описание алгоритма взятия хеша, параметры этого алгоритма и еще может быть чего. И шифруется уже этот контейнер, преобразованный в массив байт вполне конкретным способом.

Можете назвать еще хоть одну массовую, не нишевую, область, где ASN.1 используется?

Я могу назвать с десяток (вроде LDAP, SNMP, H.323, UMTS, LTE, WiMAX, 3GPP и вообще очень много всего в том, что касается телекомов и вокруг них), но вы удобно скажете, что это все "нишевые области". Впрочем, чем тогда "криптография" не нишевая?

Или даже так: работа с ASN.1 почти всегда подразумевает касание криптографии.

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

И вот в посте ровно пример того, где работа с ASN.1 ну совсем никак не связана с использованием криптографии. Ничего не шифруется или подписывается с целью сокрытия содержания или защиты от изменений. Сертификат используется просто как источник данных. Если бы эти данные можно было получить, обратившись в какую-нибудь БД или веб-сервис — скорее всего так бы и сделали, а не разбирали сертификаты.

Телеком — это именно что нишевая область. Криптография не нишевая, потому что это чисто утилитарная область, само по себе она никому не сдалась, нужна только вместе с чем-то. И областей, требующих для себя криптографии, вполне много.

И вот в посте ровно пример того, где работа с ASN.1 ну совсем никак не связана с использованием криптографии

Ну да, ничего не шифруется и не проверяется. Согласен. Однако работать с ASN.1 приходится под соусом криптографии. Даже парсер ASN.1 является частью криптографической библиотеки, а не отдельной библиотекой. Потому что там он не абстрактный парсер контейнеров с информацией, а все-таки наделяет эти контейнеры каким-то смыслом. Вот здесь у нас ContentInfo , здесь SignedData , а здесь EnvelopedData . Это уже часть криптографической библиотеки. Можно эти структуры считать "средствами… преобразования информации" из приведенного вами определения?

Когда занимался такими же задачами, то вместо ASN1 Editor использовал asn1js. Который отлично работает со строками. В ASN1 есть несколько типов строк, и ASN1 Editor кириллицу отображает плохо. А доработать код на C++ для поддержки Unicode не так-то просто.

И сделал пару доработок для asn1js, чтобы отображать СНИЛС, ИНН,… и иметь удобный способ сравнивать сертификаты/подписи.

К комитам есть скриншоты, посмотрите, может пригодится:

print description — классная фича, жалко, что похоже автор pull request-ы почему-то не принимает, но отослать все равно надо бы

Главная > Документ

Информация о документе
Дата добавления:
Размер:
Доступные форматы для скачивания:

Приложение № 12

к Регламенту Удостоверяющего центра Федерального казначейства,

утвержденному приказом Федерального казначейства от ___.___.2013 №_____

Формат и структура сертификата ключа подписи

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

Сертификат ключа проверки электронной подписи в электронной форме представляет собой электронный документ, имеющий структуру, соответствующую стандарту Международного союза телекоммуникаций ITU-T X.509 версии 3 и рекомендаций IETF (Internet Engineering Task Force) RFC 3280 и 5280 и представленный в кодировке Base64.

Структура сертификатов ключей подписи, изготавливаемых УЦ, определяется следующей таблицей:

admin

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

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