Не ждем, а готовимся к переходу на новые стандарты криптографической защиты информации

В информационном мире и Digital-Банке само собой разумеется — Digital Security и Digital Signature.

fqt5qu5bslukaob3aa62lgoxgju.jpegКриптография позволяет нам защитить информацию от подмены и однозначно установить ее правообладателя посредством усиленной электронной подписи.

Криптография дает возможность закрыть для посторонних глаз информацию конфиденциального характера с помощью шифрования.

Как применять криптографию в соответствии с законодательством и ладу с регуляторами?

Речь пойдет о правовых аспектах и об организационно-технических мероприятиях в рамках официального перехода на национальные стандарты в области криптографической защиты информации ГОСТ Р 34.11–2012 «Функция хэширования» и ГОСТ Р 34.10–2012 «Процессы формирования и проверки электронной цифровой подписи».

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

Правовые аспекты


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

Федеральным законом от 4 мая 2011 г. № 99-ФЗ «О ЛИЦЕНЗИРОВАНИИ ОТДЕЛЬНЫХ ВИДОВ ДЕЯТЕЛЬНОСТИ» установлен перечень видов деятельности, подлежащих обязательному лицензированию.

Постановлением Правительства РФ № 957 от 21 ноября 2011 г. «ОБ ОРГАНИЗАЦИИ ЛИЦЕНЗИРОВАНИЯ ОТДЕЛЬНЫХ ВИДОВ ДЕЯТЕЛЬНОСТИ» утвержден «ПЕРЕЧЕНЬ ФЕДЕРАЛЬНЫХ ОРГАНОВ ИСПОЛНИТЕЛЬНОЙ ВЛАСТИ, ОСУЩЕСТВЛЯЮЩИХ ЛИЦЕНЗИРОВАНИЕ КОНКРЕТНЫХ ВИДОВ ДЕЯТЕЛЬНОСТИ»

К лицензируемым видам деятельности, которые курирует ФСБ РФ, относятся:

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


31 января 2014 выходит документ ФСБ России № 149/7/⅓–58 «О порядке перехода к использованию новых стандартов ЭЦП и функции хэширования».

Здесь я позволю себе процитировать выписку из данного документа, которая опубликована на портале ТЕХНИЧЕСКОГО КОММИТЕТА ПО СТАНДАРТИЗАЦИИ «КРИПТОГРАФИЧЕСКАЯ ЗАЩИТА ИНФОРМАЦИИ» (ТК 26)

«Для средств ЭП, техническое задание на разработку которых утверждено после 31 декабря 2012 года, должна быть предусмотрена реализация функций средства в соответствии с ГОСТ Р 34.10–2012 хотя бы по одному из определяемых стандартом вариантов требований к параметрам (использование варианта, соответствующего длине секретного ключа порядка 256 бит, является предпочтительным, поскольку обеспечивает достаточный уровень криптографической стойкости и лучшие эксплуатационные характеристики, в том числе при совместной реализации со схемой ГОСТ Р 34.10–2001). После 31 декабря 2013 года не осуществлять подтверждение соответствия средств ЭП Требованиям к средствам электронной подписи, утверждённым приказом ФСБ России от 27.12.2011 г. № 796, если в этих средствах не предусмотрена реализация функций средства в соответствии с ГОСТ Р 34.10–2012 хотя бы по одному из определяемых стандартом вариантов требований к параметрам. Исключение может быть сделано для средств ЭП, удовлетворяющих одновременно следующим условиям:
 — техническое задание на разработку средства утверждено до 31 декабря 2012 года;
 — в соответствии с техническим заданием разработка средства завершена после 31 декабря 2011 года;
 — подтверждение соответствия средства указанным Требованиям ранее не осуществлялось.
Использование схемы подписи ГОСТ Р 34.10–2001 для формирования подписи после 31 декабря 2018 года не допускается.»


На кого нацелен этот документ?

  • он нацелен в первую очередь на лицензированных разработчиков СКЗИ, которые сертифицируют свои криптографические провайдеры в ФСБ.
  • на уполномоченный федеральный орган в области использования электронной подписи и одновременно Головной Удостоверяющий Центр (ГУЦ), которым в соответствии с Федеральным законом № 63 «Об электронной подписи» и Постановлением Правительства РФ №976 от 28.11.2011 является Министерство связи и массовых коммуникаций
  • на удостоверяющие центры, которые в соответствии со статьей 16 ФЗ № 63 «Об электронной подписи» получают аккредитацию в ГУЦ «Минкомсвязь»
  • на организации, например, Альфа-Банк, которые осуществляют коммерческую деятельность с применением средств криптографической защиты информации.


В Постановлении Правительства России от 16 апреля 2012 г. №313 «Об утверждении Положения о лицензировании деятельности по разработке, производству, распространению шифровальных (криптографических) средств, информационных систем и телекоммуникационных систем, защищенных с использованием шифровальных (криптографических) средств, выполнению работ, оказанию услуг в области шифрования информации, техническому обслуживанию шифровальных (криптографических) средств, информационных систем и телекоммуникационных систем, защищенных с использованием шифровальных (криптографических) средств (за исключением случая, если техническое обслуживание шифровальных (криптографических) средств, информационных систем и телекоммуникационных систем, защищенных с использованием шифровальных (криптографических) средств, осуществляется для обеспечения собственных нужд юридического лица или индивидуального предпринимателя)»

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

Например, пункт из перечня: »2. Разработка защищенных с использованием шифровальных (криптографических) средств информационных систем»

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

В пункте 6 Положения №313 приведены лицензионные требования к организациям лицензиатам.

На этом с правовыми аспектами, которые порой трудно читать, закончим. И перейдем к организационным мероприятиям.

Взаимодействие с регулятором


ГУЦ «Минкомсвязь» имеет свой портал — это своего рода единая точка входа в (Public Key Infrastructure PKI) Инфраструктуру с открытым ключом в масштабах Российской Федерации. Там опубликован большой список нормативных документов, требования и порядок аккредитации удостоверяющих центров, реестр действующих аккредитованных УЦ и информация о доступности их сервисов.

Там же можно скачать XML-представление реестра аккредитованных УЦ

TSL — Trusted List of supervised/accredited Certification Service Providers. Этот список подписан электронной подписью Минкомсвязи, через него выстраивается доверие и пути сертификации.

В целом на площадке Госуслуги развернуто единое пространство Электронного правительства РФ. Большинство сервисов, которого стало возможным благодаря развертыванию национальной PKI и применению криптографии и квалифицированной электронной подписи.

Так, например, в сервисах шины Системы межведомственного электронного взаимодействия СМЭВ используется квалифицированная электронная подпись, сертификаты открытого ключа которой заверены аккредитованными удостоверяющими центрами национальной PKI.

В свете сказанного выше было принято решение задать следующие вопросы в Федеральный ситуационный центр электронного правительства (адрес sd@sc.minsvyaz.ru).

Мое письмо было принято в работу группой ГУЦ-Восход:

Здравствуйте!
В соответствии с выпиской из документа ФСБ России № 149/7/⅓–58 от 31.01.2014 «О порядке перехода к использованию новых стандартов ЭЦП и функции хэширования»,
Где говорится, что использование ГОСТ Р 34.10–2001 для формирования подписи после 31 декабря 2018 года не допускается и необходимо выполнить переход на новые стандарты ГОСТ Р 34.10–2012, ГОСТ Р 34.11–2012

Сообщите, пожалуйста, какого плана работы предусмотрены для осуществления перевода инфраструктуры Головного удостоверяющего центра Минкомсвязи России на работу с ГОСТ Р 34.10–2012, ГОСТ Р 34.11–2012

Будут ли меняться:

  • корневой сертификат ГУЦ Минкомсвязи России?
  • сертификаты ПАК «УЦ 1 ИС ГУЦ» и ПАК «УЦ 2 ИС ГУЦ» ?
  • сертификат подписи TSLExt1.0.xml списка аккредитованных УЦ?
  • (STREET=125375 г. Москва ул. Тверская д. 7, CN=Подсистема «Реестры» ИС ГУЦ, O=Минкомсвязь России, L=Москва, ST=77 г. Москва, C=RU)
  •  — структура самого TSL-списка, опубликованного на портале e-trust.gosuslugi.ru/CA/DownloadTSL? schemaVersion=0?

В какие сроки планируется проводить изменения и работы?

Будут ли какие-то предварительные объявления на портале e-trust.gosuslugi.ru?

Что будет со старыми типами подписи СМЭВ?

jmp4csvrdocnceadsdjws1skxea.png




Будет единовременный переход на СМЭВ 3 с новым алгоритмом подписи?

И получил следующие ответы:

Добрый день!

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

Переход Головного удостоверяющего центра на новые госты планируется в первом полугодии 2018 года, соответственно сертификат ГУЦ Минкомсвязи России будет заменен в это же время.
Сертификаты УЦ 1 ИС ГУЦ и УЦ 2 ИС ГУЦ и сертификат подписи TSL предположительно будут заменены в это же время.

Структуру TSL списка менять не планируется.

Информация о работах по переходу на новые госты будет опубликована на странице sc.minsvyaz.ru и minsvyaz.ru/ru/appeals/faq/66

Согласно вышеописанной выписке, после 1 января 2019 года не допускается формирование подписи на старых ГОСТ, т.е., исходя из нее, дожить они могут, но подписывать ими нельзя. Обязательный отзыв сертификатов на старых ГОСТ пока также не планируется. Перевод своих клиентов на новые ГОСТ аккредитованный УЦ осуществляет самостоятельно, по мере своих возможностей, какого-либо общего порядка по нему не предусмотрено.

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


Вопросы касательно СМЭВ я сформулировал в отдельном письме на тот же адрес и оно было маршрутизировано на группу PТК-CМЭВ, а затем команде ПАО «Ростелеком».

Получен такой ответ:

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


Вообще СМЭВ и подпись XMLDsig/XAdES это отдельная большая тема.

Постановка задачи


Цели:

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


В общем, стало понятно, что нужно не ждать регуляторов, а готовиться.

Тем более, почти все необходимое под рукой есть. Сертифицированные СКЗИ, поддерживающие новые алгоритмы КриптоПро CSP 4.0, Java API КриптоПро JCSP и КриптоПро JCP 2.0 есть.

Выполнить генерацию новых ключей можно.

Нужен был только УЦ в PKCS#10 запросе на сертификат, к которому мы сможем передать свой открытый ключ, сгенерированный по новому алгоритму. Но об этом чуть позже.

Бесперебойная работа ПО


На сайте КриптоПро регулярно выходили новости об автоматическом включении в СКЗИ предупреждений про грядущий переход на новые стандарты, по требованию ФСБ РФ.

В Базе знаний портала технической поддержки размещена подробная информация об этих предупреждениях, и как их отключить в версиях СКЗИ под различные операционные системы:

Обращаем внимание, что в связи с требованиями ФСБ России, сопряженными с запретом использования ГОСТ Р 34.10–2001 для формирования подписи после 1 января 2019 года (см. tc26.ru/info/new-national-standards), с 1 июля 2017 года в КриптоПро CSP версий 3.9 и 4.0, а также КриптоПро JCP 2.0 будут появляться предупреждения о необходимости скорого перехода на ГОСТ Р 34.10–2012 при формировании ключей ГОСТ Р 34.10–2001, а с 1 октября 2017 года — и при формировании подписи по ГОСТ Р 34.10–2001. Пользователь, обладающий правами администратора системы, при запуске приложения с правами администратора (UAC) может отложить предупреждения на месяц, установив соответствующий флаг в данном окне.
На случай если появление этих предупреждений в вашей системе нежелательно, вы можете заблаговременно их отключить.


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

За примером далеко ходить не надо. Возьмем операционную систему Linux, информационную систему на Java и провайдер КриптоПро JCP 2.0, посредствам которого выполняется электронная подпись документов. Если не отключить своевременно уведомления о переходе на новые стандарты, то в информационной системе при попытке подписать документ возникнет ошибка:

ERROR: java.awt.HeadlessException: 
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
	at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:204)
	at java.awt.Window.(Window.java:536)
	at java.awt.Frame.(Frame.java:420)
	at java.awt.Frame.(Frame.java:385)
	at javax.swing.JFrame.(JFrame.java:189)
	at ru.CryptoPro.JCP.tools.j.(Unknown Source)
	at ru.CryptoPro.JCP.tools.Gost2001Warning.warn(Unknown Source)
	at ru.CryptoPro.JCP.Sign.a.engineInitSign(Unknown Source)
	at java.security.Signature.initSign(Signature.java:527)
	at ru.CryptoPro.JCPxml.xmldsig.SignatureGostR3410.engineInitSign(Unknown Source)
	at org.apache.xml.security.algorithms.SignatureAlgorithm.initSign(SignatureAlgorithm.java:238)
	at org.apache.xml.security.signature.XMLSignature.sign(XMLSignature.java:591)


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

В итоге предупреждение приводит к сбою в программе, подпись на документ не ставится.

Разумеется, для информационной системы, где идет поток обращений к провайдеру, запускать сервер X Window System, например, программу Xming на своей станции и подключаться с помощью PuTTY по SSH с включенной опцией X11 forwarding для того, что бы клиент КриптоПро JCP мог отображать все предупреждения на нашу станцию, мы не будем.

Поэтому отключаем уведомления в контрольной панели КриптоПро JCP, следуя инструкции.

35bkax9xiq1cpz0tcleknx_muyo.png

Если информационная система на Java использует криптографический провайдер КриптоПро CSP через JavaCSP, то выполняем пункт инструкции:

Для отключения данных предупреждений в КриптоПро CSP до 1 января 2019 года на Unix-системах нужно добавить два ключа в конфигурационный файл /etc/opt/cprocsp/config64.ini (или /etc/opt/cprocsp/config.ini в случае 32-битной системы) в существующую секцию Parameters:


6t4blgbuq9l55-fpkrebxlqfw0s.png

Соответствующие напоминания КриптоПро CSP появляются при генерации ключей и нового запроса на сертификат в UI центра регистрации. Если указать в поле Криптопровайдер — Crypto-Pro GOST R 34.10–2001 Cryptographic Service Provider.
Для новой ключевой пары будет появляться окно с предупреждением вида:

bpohpqvqqya0mrocdxbosigdfmi.png

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

Предупреждения СКЗИ вовремя отключены, они больше не смогут привести к сбою в наших информационных системах.

Получение новых сертификатов


У КриптоПро есть свои тестовые удостоверяющие центры

На момент написания статьи УЦ поддерживающий новые стандарты отсутствовал.

Мной было заведено обращение на на портал технической поддержки КриптоПро

Скажите, пожалуйста, планируется ли перевод тестового УЦ testca2.cryptopro.ru/UI на ГОСТ Р 34.10–2012 и если да, то в какие сроки?


Был получен ответ:

Планируется, сроки не определены. Возможно это будет другой УЦ.


Сейчас есть ссылка, но пока она не работоспособна и не изменится ли она не известно.

Помощь с получением сертификатов оказало подразделение информационной безопасности. Был развернут собственный экземпляр тестового центра сертификации, поддерживающий ГОСТ 34.10–2012

yjqkez4ufgrgww_g711qgc7ti8k.png

Выполнена генерация двух комплектов ключей с размерностями 256 и 512 бит и получены два сертификата, соответствующие новым стандартам ГОСТ Р 34.10–2012, ГОСТ Р 34.11–2012.

dl5m5uu73dzpfazn_q6qex8xahu.png

jioibx8ebla5oio7z8kpnadu60q.png

Подпись документа и проверка


Напомню, в составе КриптоПро JCP можно найти много примеров в файле samples-sources.jar. В частности, там есть примеры подписи и проверки ЭП документов. Все остальное является по большому счету частными кастомизациями.

Провайдеры КриптоПро JCP и JCSP поддерживают следующие нужные нам алгоритмы хэш функции и подписи:

JCSP - CryptoPro Java CSP Provider
JCP - CryptoPro Java Provider

MessageDigest — GOST3411_2012_256
MessageDigest — GOST3411_2012_512

Signature — GOST3411_2012_256withGOST3410DH_2012_256
Signature — GOST3411_2012_512withGOST3410DH_2012_512

Как красиво распечатать список установленных и готовых к работе в JVM криптографических провайдеров, поддерживаемых ими функций и реализуемых алгоритмов:

// Распечатка всех криптопровайдеров 
                try {
                    for (Provider p : Security.getProviders()) {
                        LOGGER.info(p.getName() + " - " + p.getInfo());
                        @SuppressWarnings("unchecked")
                        ArrayList propNames = (ArrayList) Collections.list(p.propertyNames());
                        Collections.sort(propNames);
                        Set services = new TreeSet(new Comparator() {
                            
                            @Override
                            public int compare(Service s1, Service s2) {
                                int res = s1.getType().compareTo(s2.getType());
                                if (res == 0) {
                                    res = s1.getAlgorithm().compareTo(s2.getAlgorithm());
                                }
                                return res;
                            }
                            
                            @Override
                            public Comparator reversed() {
                                return null;
                            }
                            
                            @Override
                            public Comparator thenComparing(Comparator arg0) {
                                return null;
                            }
                            
                            @Override
                            public > Comparator thenComparing(Function arg0) {
                                return null;
                            }
                            
                            @Override
                            public  Comparator thenComparing(Function arg0, Comparator arg1) {
                                return null;
                            }
                            
                            @Override
                            public Comparator thenComparingDouble(ToDoubleFunction arg0) {
                                return null;
                            }
                            
                            @Override
                            public Comparator thenComparingInt(ToIntFunction arg0) {
                                return null;
                            }
                            
                            @Override
                            public Comparator thenComparingLong(ToLongFunction arg0) {
                                return null;
                            }
                            
                        });
                        services.addAll(p.getServices());
                        for (Service s : services) {
                            LOGGER.info("   " + s.getType() + " - " + s.getAlgorithm());
                        }
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                } 


Для того чтобы существующие методы подписи по ГОСТ Р 34.10–2001 начали подписывать документ по ГОСТ Р 34.10–2012, потребовалось внести ряд небольших изменений.

Рассмотрим на примере создания CMS (PKCS#7) контейнера.

Добавить названия новых алгоритмов:

    private static final String GOST3411_2012_256 = "GOST3411_2012_256";
    private static final String GOST3411_2012_256WITH_GOST3410DH_2012_256 = "GOST3411_2012_256withGOST3410DH_2012_256";
    private static final String GOST3411_2012_512 = "GOST3411_2012_512";
    private static final String GOST3411_2012_512WITH_GOST3410DH_2012_512 = "GOST3411_2012_512withGOST3410DH_2012_512";


Инициализировать объект подписи с нужным алгоритмом:

Signature signature = Signature.getInstance(GOST3411_2012_512WITH_GOST3410DH_2012_512,config.getProperty(Config.CRYPTO_PROVIDER));


Добавить в создаваемый CMS контейнер нужный идентификатор хэш-функции:

 final DigestAlgorithmIdentifier digestAlgorithmIdentifier = new DigestAlgorithmIdentifier(new OID(JCP.GOST_DIGEST_2012_512_OID).value);
        digestAlgorithmIdentifier.parameters = new Asn1Null();
        cms.digestAlgorithms.elements[0] = digestAlgorithmIdentifier;


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

for (int i = 0; i < cms.signerInfos.elements.length; i++) {
            cms.signerInfos.elements[i].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(JCP.GOST_DIGEST_2012_512_OID).value);
            cms.signerInfos.elements[i].digestAlgorithm.parameters = new Asn1Null();
            cms.signerInfos.elements[i].signatureAlgorithm = new SignatureAlgorithmIdentifier(
            new OID(JCP.GOST_PARAMS_SIG_2012_512_KEY_OID).value);
            cms.signerInfos.elements[i].signatureAlgorithm.parameters = new Asn1Null();


В этом же цикле выполняем хэширование:

messageDigestBlob = calculateDigestm(data, GOST3411_2012_512, config.getProperty(Config.CRYPTO_PROVIDER));
            
            final Asn1Type messageDigest = new Asn1OctetString(messageDigestBlob);
            cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = messageDigest;


И здесь же создаем четвертый подписываемый атрибут, содержащий хэш сертификата открытого ключа проверки этой подписи

cms.signerInfos.elements[i].signedAttrs.elements[k] = new Attribute(
                        new OID(ALL_PKIX1Explicit88Values.id_aa_signingCertificateV2).value, new Attribute_values(1));
                
                // Идентификатор алгоритма хэширования, который использовался
                // для
                // хэширования контекста сертификата ключа подписи.
                final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(new OID(JCP.GOST_DIGEST_2012_512_OID).value);
                
                // Хш сертификата ключа подписи.
                final CertHash certHash = new CertHash(calculateDigestm(certificateList.get(i).getEncoded(), GOST3411_2012_512,
                        config.getProperty(Config.CRYPTO_PROVIDER)));
                
                // Issuer name из сертификата ключа подписи.
                GeneralName generalName = new GeneralName();
                generalName.set_directoryName(name);
                
                GeneralNames generalNames = new GeneralNames();
                generalNames.elements = new GeneralName[1];
                generalNames.elements[0] = generalName;
                
                // Комбинируем издателя и серийный номер.
                IssuerSerial issuerSerial = new IssuerSerial(generalNames, num);
                
                ESSCertIDv2 essCertIDv2 = new ESSCertIDv2(a, certHash, issuerSerial);
                
                _SeqOfESSCertIDv2 essCertIDv2s = new _SeqOfESSCertIDv2(1);
                essCertIDv2s.elements = new ESSCertIDv2[1];
                essCertIDv2s.elements[0] = essCertIDv2;
                
                // Добавляем сам аттрибут.
                SigningCertificateV2 signingCertificateV2 = new SigningCertificateV2(essCertIDv2s);
                cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = signingCertificateV2;


Это все места, где при подписании нужно указать новый алгоритм.

Для проверки подписи в другом классе добавляем названия алгоритмов и новые OID-ы.

private static final String GOST3411_2012_256WITH_GOST3410DH_2012_256 = "GOST3411_2012_256withGOST3410DH_2012_256";
    private static final String GOST3411_2012_512WITH_GOST3410DH_2012_512 = "GOST3411_2012_512withGOST3410DH_2012_512";
    
    private static final OID OID_ALG_DIGEST_GOST_2012_256 = new OID("1.2.643.7.1.1.2.2");
    private static final OID OID_ALG_SIGN_GOST_2012_256 = new OID("1.2.643.7.1.1.1.1");
    private static final OID OID_ALG_DIGEST_GOST_2012_512 = new OID("1.2.643.7.1.1.2.3");
    private static final OID OID_ALG_SIGN_GOST_2012_512 = new OID("1.2.643.7.1.1.1.2");


Идентификаторы OID и их древовидная структура описаны в стандартах ASN.1 ITU-T X.660 и ISO/IEC 9834. Стандарты и информацию, какой идентификатор, какой сущности привязан можно найти на oid-info.com

Правда, идентификаторы новых алгоритмов пока не добавлены в российский сегмент OID-ов. Переход ведь только грядет. А вот по алгоритмам 2001 года информация есть:

private static final OID OID_S_ALG_DIGEST_GOSTBC = new OID("1.2.643.2.2.9");
private static final OID OID_S_ALG_SIGN_GOSTBC = new OID("1.2.643.2.2.19");


Далее в методе проверки подписи проверяем, что алгоритм хэш-функции, указанный в CMS-контейнере нам знаком:

if ((!signedData.digestAlgorithms.elements[0].algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_S_ALG_DIGEST_GOSTBC).value)))
                    && (!signedData.digestAlgorithms.elements[0].algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_ALG_DIGEST_GOST_2012_256).value)))
                    && (!signedData.digestAlgorithms.elements[0].algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_ALG_DIGEST_GOST_2012_512).value)))) {
                throw new SignatureVerificationException("Unexpected SignedData digest algorithm: " + signedData.digestAlgorithms.elements[0].algorithm);
            }


Выполняем проверку алгоритмов digest-а и signature для каждой подписи внутри контейнера:

for (ru.CryptoPro.JCP.ASN.CryptographicMessageSyntax.SignerInfo signerInfo : signedData.signerInfos.elements) {
                SignatureVerificationResult svr = new SignatureVerificationResult();
                result.getSignatureVerificationResultList().add(svr);
                //TODO  включить контроль алгоритмов подписи и хэширования
                if ((!signerInfo.digestAlgorithm.algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_S_ALG_DIGEST_GOSTBC).value)))
                        && (!signedData.digestAlgorithms.elements[0].algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_ALG_DIGEST_GOST_2012_256).value)))
                        && (!signedData.digestAlgorithms.elements[0].algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_ALG_DIGEST_GOST_2012_512).value)))) {
                    throw new SignatureVerificationException("Unexpected digest algorithm: " + signerInfo.digestAlgorithm.algorithm);
                }
                if ((!signerInfo.signatureAlgorithm.algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_S_ALG_SIGN_GOSTBC).value)))
                        && (!signerInfo.signatureAlgorithm.algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_S_ALG_CADES).value)))
                        && (!signerInfo.signatureAlgorithm.algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_S_ALG_DIGEST_GOSTBC).value)))
                        && (!signerInfo.signatureAlgorithm.algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_ALG_SIGN_GOST_2012_256).value)))
                        && (!signerInfo.signatureAlgorithm.algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_ALG_SIGN_GOST_2012_512).value)))) {
                    throw new SignatureVerificationException("Unexpected signature algorithm: " + signerInfo.signatureAlgorithm.algorithm);
                }


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

MessageDigest digester = MessageDigest.getInstance(new OID(signerInfo.digestAlgorithm.algorithm.value).toString(), config.getProperty(Config.CRYPTO_PROVIDER));


Инициализируем объект класса Signature c соответствующим алгоритмом:

Signature signature = null;
                if (signerInfo.signatureAlgorithm.algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_ALG_SIGN_GOST_2012_256).value))) {
                    signature = Signature.getInstance(GOST3411_2012_256WITH_GOST3410DH_2012_256, config.getProperty(Config.CRYPTO_PROVIDER));
                } else if (signerInfo.signatureAlgorithm.algorithm.equals(new Asn1ObjectIdentifier(new OID(OID_ALG_SIGN_GOST_2012_512).value))) {
                    signature = Signature.getInstance(GOST3411_2012_512WITH_GOST3410DH_2012_512, config.getProperty(Config.CRYPTO_PROVIDER));
                } else {
                    signature = Signature.getInstance(GOST3411WITH_GOST3410DHEL, config.getProperty(Config.CRYPTO_PROVIDER));
                }


На этом все нюансы программного перехода на стандарты ГОСТ 34.10–2012 и ГОСТ 34.11–2012 исчерпаны.

Наше программное обеспечение готово подписывать документы и проверять подписи по новому стандарту с размерностью ключа 256 и 512 бит.

Вот так выглядит структура CMS с новыми идентификаторами алгоритмов в программе ASN1View (разработчик)

r7ivjscstlkvmfgirgxrp9t9ijw.jpeg

Результат проверки подписи PKCS-7 ГОСТ Р 34.11–2012/34.10–2012 256 бит


 — в сервисе проверки ЭП на портале Госуслуги

nq6kqb8-91xv4hu3jddmptwfcug.png

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

— с помощью программы КриптоАрм

eyxraps4yqkt0btpe1q8wegimtg.png

f9eb2zijyvmeilulj_zdc2txetu.png

3vcbe6y1bd-z84wjmfoer_4eoau.png

mdkuqi5wedz1q4unojh6fwqmjvo.png

awicjkcphrqrr9jk9rwed37bwtu.png

— в собственном программном обеспечении

dlck6steafjrpehcbvlkcgstrb4.png

Результат проверки подписи PKCS-7 ГОСТ Р 34.11–2012/34.10–2012 512 бит


 — в сервисе проверки ЭП на портале Госуслуги

jgz9e-xqk8n7quifzm2o5ra-8-q.png

— с помощью программы КриптоАрм

yzrburwiuafhnl-p_s443rhkx8k.png

_q3gwllnlrjwccwma_keusdaols.png

В КриптоАРМ сертификат проверки ЭП считается действительным, потому что корневой сертификат нашего тестового УЦ я добавил в хранилище корневых доверенных центров сертификации своей операционной системы.

— в собственном программном обеспечении

bl8j6w2ldacpskwajam1_rmyjfq.png

Полезные ссылки


  1. Портал ТЕХНИЧЕСКОГО КОММИТЕТА ПО СТАНДАРТИЗАЦИИ «КРИПТОГРАФИЧЕСКАЯ ЗАЩИТА ИНФОРМАЦИИ»
  2. Портал ГУЦ «Минкомсвязь»
  3. Федеральный ситуационный центр электронного правительства
  4. База знаний портала технической поддержки КриптоПро
  5. Идентификаторы OID и их древовидная структура в стандартах ASN.1 ITU-T X.660 и ISO/IEC 9834 на oid-info.com
  6. Тестовый удостоверяющий центр КриптоПро
  7. Проверка сертификатов и документов с ЭП на портале Госуслуги
  8. Сайт разработчика КриптоАрм

© Habrahabr.ru