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

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

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

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

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

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

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


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

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

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

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

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

31 января 2014 выходит документ ФСБ России № 149/7/1/3-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/1/3-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?

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



<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001gostr3411"/>
</ds:SignedInfo>

Будет единовременный переход на СМЭВ 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.<init>(Window.java:536)
	at java.awt.Frame.<init>(Frame.java:420)
	at java.awt.Frame.<init>(Frame.java:385)
	at javax.swing.JFrame.<init>(JFrame.java:189)
	at ru.CryptoPro.JCP.tools.j.<init>(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, следуя инструкции.



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

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



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



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

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

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


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

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

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

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

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

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

Сейчас появилась живая ссылка на тестовый УЦ КриптоПро, поддерживающий ГОСТ 2012.

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



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





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


Напомню, в составе КриптоПро 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<String> propNames = (ArrayList<String>) Collections.list(p.propertyNames());
                        Collections.sort(propNames);
                        Set<Service> services = new TreeSet<Service>(new Comparator<Service>() {
                            
                            @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<Service> reversed() {
                                return null;
                            }
                            
                            @Override
                            public Comparator<Service> thenComparing(Comparator<? super Service> arg0) {
                                return null;
                            }
                            
                            @Override
                            public <U extends Comparable<? super U>> Comparator<Service> thenComparing(Function<? super Service, ? extends U> arg0) {
                                return null;
                            }
                            
                            @Override
                            public <U> Comparator<Service> thenComparing(Function<? super Service, ? extends U> arg0, Comparator<? super U> arg1) {
                                return null;
                            }
                            
                            @Override
                            public Comparator<Service> thenComparingDouble(ToDoubleFunction<? super Service> arg0) {
                                return null;
                            }
                            
                            @Override
                            public Comparator<Service> thenComparingInt(ToIntFunction<? super Service> arg0) {
                                return null;
                            }
                            
                            @Override
                            public Comparator<Service> thenComparingLong(ToLongFunction<? super Service> 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 (разработчик)



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


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



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

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











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



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


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



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





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

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



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


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

Комментарии (10)


  1. maxdm
    02.11.2017 13:51

    Коллеги подсказывают, что тестовый УЦ на базе УЦ 2.0 и ГОСТ 34.10-2012 уже готов, ждём обновления DNS.
    А первый из тестовых центров тоже поддерживает ГОСТ, но защищен ГОСТ TLS.


    1. vburmistrov Автор
      02.11.2017 15:01
      +1

      maxdm,
      Спасибо за информацию!

      Действительно появилась еще одна ссылка на УЦ, которая функционирует.

      В статье актуализировал:

      Сейчас появилась живая ссылка на тестовый УЦ КриптоПро, поддерживающий ГОСТ 2012.

      Сам тоже собирался этот вопрос держать под наблюдением.


  1. mustiks
    02.11.2017 15:28

    А с чем связан запрет на использование старого ГОСТ, уязвимость, неудобство использование или другие причины?


    1. vburmistrov Автор
      02.11.2017 15:35

      mustiks, алгоритмы из старых стандартов пока не запрещают.
      Если Вы будете применять их сугубо для внутреннего использования, то это сколько угодно.

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

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

      Аккредитованные УЦ обязаны перейти на новые стандарты.
      Разработчики СКЗИ для получения в ФСБ сертификата соответствия обязаны реализовать у себя криптографию по новым стандартам.

      С технической точки зрения цель перехода — повышение уровня криптографической стойкости и улучшение эксплуатационных характеристик.


      1. mustiks
        02.11.2017 21:31

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


        1. vburmistrov Автор
          03.11.2017 09:56
          +1

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

          Какое-то время будут поддерживаться оба типа стандартов. Конкретная дата проведения работ в СМЭВ не определена.


      1. JokerOfGod
        03.11.2017 03:26

        Спасибо! V


        1. vburmistrov Автор
          03.11.2017 10:12
          +1

          Рад, если оказалось полезным, вместе победим! V


  1. rumkin
    03.11.2017 09:09

    Как в банковской сфере дела обстоят с эллиптикой на основе ed25519? Правильно ли я понимаю, что практика использования в блокчейне-проектах в данном случае не показатель для сферы финансов?


    1. vburmistrov Автор
      03.11.2017 10:11
      +1

      Отвечу, как один небезызвестный персонаж:

      «Нам ничего об этом не известно»

      А если серьезно: то за всю банковскую сферу ответить не могу, в моей деятельности больше всего приходится иметь дело с ГОСТ эллиптикой.

      К сожалению попробовать ed25519 пока не доводилось.

      Правильно говорит Scratch в своей статье: Curve25519, EdDSA и Poly1305: Три обделенных вниманием криптопримитива.

      Спасибо за напоминание про эту область. Обязательно хотя бы для себя попробую покопать.