И вот, когда я уже практически добавил в криптографический АРМ на базе токенов PKCS#11 cryptoarmpkcs генерацию самоподписанных сертификатов и готов был приступить к написанию статьи, мне пришло такое письмо:
Мы являемся УЦ «Имярек», у нас возникло затруднение с выпуском ЭП в формате pkcs#11 для ЕГАИС, портал не понимает ЭП в формате «Имярек» CSP, просим Вас помочь в данной проблеме.
.
Я еще не знал всех тонкостей работы с ЕГАИС, но поскольку речь шла о PKCS#11, то предложил воспользоваться утилитой cryptoarmpkcs для генерации запроса и установки сертификата на токен после его получения из УЦ. Полученный ответ меня несколько огорошил:
Увы нет, дело обстоит в том, что мы на RuToken 2.0 записали ЭП через КриптоПро CSP, но при всех должных настройках портал ЕГАИС не увидел на ключевом носителе ЭП, клиент обратился к нам в поддержку и мы установили, что проблема в том что не в том формате записан сертификат на ключ, вот мануал dev.rutoken.ru/display/KB/RU1051
.
Я (и не только я) уже неоднократно писал, что многие используют криптографические токена с поддержкой российской криптографии как обыкновенные флэшки. И это как раз был тот случай, когда ключ и сертификат попали на токен не как объекты PKCS#11. Обидно было то, что они не воспользовались советом и даже не попытались создать запрос. Но тут я решил все отложить в сторону и разобраться как и на чем выпускаются сертификаты для ЕГАИС Росалкогольрегулирование. И рассматривать мы будем только криптографические токены PKCS#11. Самое большое разочарование — это доступ к ЕГАИС только через ОС Windows и браузер IE. С другой стороны, генерацию запроса на сертификат и установку сертификата всеже можно проводить под любой ОС, если для нее имеются драйвера/библиотеки для соответствующего токена.
По крайней мере токены PKCS#11 JaCarta, RutokenECP-2.0, программный токен LS11SW2016 и даже облачный токен имеют поддержку и на MS Windows, и на Linux, и на OS X. И не только на этих ОС.
Воообще-то, надо отдать должное разработчикам ЕГАИС. Они предложили интересную технологию, которая позволяет для доступа использовать личные сертификаты (сертификат плюс ключевая пара), хранящиеся на криптографических токенах с поддержкой российской криптографии, а канал защищать на RSA-сертификатах. Хотя если сказали А, то можно было сказать и В, т.е. защищать канал на ГОСТ-овых алгоритмах. Огорчает одно, что все это заточено только под MS Windows (или я ошибаюсь?), а точнее под Internet Explorer. А утилиты генерации запросов на сертификат для ЕГАИС привязаны к тому или иному токену.
Но утилита cryptoarmpkcs мультиплатформенная. Более того, она способна работать с любым криптографичеким токеном PKCS#11, поддерживающим российскую криптографию.
Итак, в чем же особенность запроса на сертификат для ЕГАИС? Основная особенность, — это обязательное наличие в отличительном имени владельца сертификата (DN subject) дополнительного поля unstucturedName (UN) (oid — 1.2.840.113549.1.9.2). Если владельцем сертификата будет индивидуальный предприниматель, то в это поле записывыется строка «КПП=», а если владелец юридическое лицо, то в это поле записывается строка следующего вида:
КПП=код_причины_постановки_на_налоговый_учет:
В связи с этим требование на первой странице вкладки запрос на сертификат была добавлена кнопка ЕГАИС:
Еще одна особенность заключается в том, что обладатели сертификатов для ЕГАИС могут быть лицензиатами системы декларирования ФСРАР (oid — 1.2.643.3.6.78.4.4). Это тоже необходимо учитывать при создании запроса:
После того как все поля запроса на сертификат заполнены и вы подтвердили правильность данных, будут сгенерирована ключевая пара и создан запрос:
Если просмотреть запрос, то в нем можно увидеть oid-ы (Extetnded Key Usage — Расширенное Использование Ключа), которые требуются для ЕГАИС Росалкогольрегулирование:
Здесь следует обратить внимание (на предыдущем скриншоте) на метку ключевой пары. В терминологии PKCS#11 это атрибут CKA_LABEL для открытого и закрытого ключа. Именно по такой схема создается метка (имя ключа) генератором запросов ЕГАИС для JaCarta от ФГУП «ЦентрИнформ»:
Традиционно тройка сертификат х открытый_ключ х закрытый ключ
на токене связывается через атрибут CKA_ID
:
Наиболее распространенный способ задания CKA_ID – это использование значения хэш-функции от значения открытого ключа. Именно такой способ для связывания тройки объектов используется в проекте NSS (Network Security Services). При этом в качестве хэш-функции используется алгоритм SHA1.
К сожалению, и CKA_LABEL и CKA_ID можно установить/изменить в любой момент с любым значением. Таким образом, всегда существует вероятность, что сертификат окажется связанным с чужим приватным ключом. Не нужно объяснять, к каким это приведет последствиям.
А вообще, существует ли строгий математический алгоритм, который позволяет связать тройку CKO_CERTIFICATE x CKO_PRIVATE_KEY x CKO_PUBLIC_KEY в единое целое?
Да, такой алгоритм на базе криптографических механизмов (CKM_) токена существует.
К сожалению (хотя объективно понять можно), рассматривает связку в тройке через CKA_LABEL, формируемую выше упомянутым способом. Более того и для закрытого и открытого ключей СКА_ID формируется аналогичным образом. Для ключей это просто катастрофа, т.к. как ни CKA_ID ни CKA_LABEL никак не привязаны к самому ключу. Это касается и сертификата после его установки на токен. Если при традиционном формировании CKA_ID как хэш от открытого ключа, можно вегда проверить соответствие одного другому, то при задании CKA_ID и CKA_LABEL описанным выше способом это сделать невозможно.
Может возникнуть вопрос, а как проверить соответствие для закрытого ключа? Ответ простой, — вычислив значение открытого ключа по закрытому. Что касается сертификата, то значение его открытого ключа находится, естественно, в нем. Более того, сертификат сам содержит значение CKA_ID как для владельца сертификата (Certificate Subject Key Identifier), так и для издателя сертификата (Certificate Authority Key Identifier):
Самое неприятное оказалось, что при установке сертификата проверяется не наличие закрытого ключа, а достаточно наличия только открытого ключа. В этом случае сертификат установится, но закрытого ключа на нем не будет. Еще одна проблема. Это поиск открытого ключа по ИНН. Представляете, у человека один ИНН и несколько ключей для различных сертификатов. Какой кому принадлежит? После этого становится понятным требование наличия на JaCarta только одного сертификата и одной ключевой пары:
Данная ошибка может быть связана с задвоением сертификата. В Едином клиенте JaCarta в режиме администратора на вкладке ГОСТ После ввода пин-кода должен быть виден один открытый, один закрытый ключ и сертификат. В данном случае видно задвоение ключей. Вам нужно удалить лишние. Заново вставить носитель в usb разъем и повторите попытку установки УТМ. Если ошибка не исчезла, проведите инициализацию Jacarta по инструкции ссылка 1 и заново пройдите процесс генерации.
Будем надеяться, что этот недостаток будет устранен. Вы можете спросить, а как устанавливает сертификат утилита cryptoarmpkcs для ЕГАИС. Для полной совместимости для JaCarta мы сохранили идеологии, что CKA_ID и CKA_LABEL для ключей совпадают. Но только после установки сертификата на токен и его привязке в ключевой паре. А до этого момента CKA_ID ключевой пары сохраняется равным значению хэш от открытого ключа.
После установки сертификата его можно использовать для подписания документов.
Теперь осталось всеже завершить доработку по созданию самоподписанных сертификатов и утилита cryptoarmpkcs и вместе с ней эта серия статей будет завершена:
Автор: Орлов Владимир Николаевич