- Анализ исходных данных
- Вариант 3. воспользоваться веб-сервисами
- Для документов формата pdf
- Подготовка к подписи по правилам смэв 3
- Подписать документ с помощью криптопро 5.0 — уц айтиком
- Подпись в html-форме
- Подпись в базе данных
- Подпись документов в формате xml
- Подпись многофайловых документов
- Подпись сообщений смэв 3
- Проблемы. хэш не совпадает
- Проверка подписи сообщения смэв 3
- Результаты
Анализ исходных данных
Загружаем с портала СМЭВ 3:
Если уже умеем формировать обычный XMLDSig или подписывать, например, конверты сообщений СМЭВ 2, то больше всего начинает интересовать, чем же отличается конверт с подписью СМЭВ 3 от СМЭВ 2.
Открываем пример конверта СМЭВ 3 SendRequestRequestNoAttach.xml
Вариант 3. воспользоваться веб-сервисами
Можно подписать документ любого формата, не устанавливая на компьютер специальных программ, — например, в веб-сервисе Контур.Крипто.
Это бесплатная программа, которая позволяет создать и проверить электронную подпись, зашифровать и расшифровать электронный файл. Можно подписать не только отдельный файл, но и пакет файлов или архивов. Можно создать подпись документа двумя и более лицами.
Работать в программе можно после регистрации и автоматической установки на компьютер программного обеспечения для криптографических операций. У программы интуитивно понятный интерфейс. Чтобы подписать электронный документ, необходимо:
Для документов формата pdf
Для создания и проверки электронной подписи в программах Adobe Acrobat, Adobe Reader и Adobe LiveCycle ES есть отдельный модуль КриптоПро PDF.
КриптоПро PDF прилагается бесплатно при совместном использовании с программой Adobe Reader. В остальных программах также есть тестовый период, по истечении которого нужно приобрести лицензию.
Прежде чем вставить электронную подпись в документе PDF, необходимо установить и настроить Acrobat Reader DC или Adobe Acrobat Pro для работы с программой КриптоПро PDF.
После настройки чтобы поставить подпись, выберете в меню документа пункт «Работа с сертификатами», затем нажмите «Подписание». Программа предложит выбрать нужную подпись, среди установленных и место в документе, где будет располагаться подпись. После этого можно завершить подписание документа.
Подготовка к подписи по правилам смэв 3
Apache Santuario изначально ничего не знает про ГОСТ криптографические алгоритмы и СКЗИ КриптоПро.
В библиотеке xmlsec-1.5.0.jar в файле orgapachexmlsecurityresourceconfig.xml содержатся настройки только для работы с зарубежными криптографическими алгоритмами.
Чтобы он начал распознавать и применять ГОСТ, нужно выполнить его инициализацию.
По старинке это делалось так:
//APACHE-SANTUARIO INIT WITH CryptoPro JCP
System.setProperty("org.apache.xml.security.resource.config", "resource/jcp.xml");
org.apache.xml.security.Init.init();
String cfile1 = System.getProperty("org.apache.xml.security.resource.config");
LOGGER.log(Level.INFO, "Init class URL: " org.apache.xml.security.Init.class.getProtectionDomain().getCodeSource().getLocation());
LOGGER.log(Level.INFO, cfile1);
В новых версиях КриптоПро JCP (JCSP) инициализацию выполнит одна строчка:
ru.CryptoPro.JCPxml.xmldsig.JCPXMLDSigInit.init();
Теперь нужно Apache Santuario научить новым правилам трансформации, которые диктует СМЭВ 3. Для этого регистрируем класс трансформации:
try {
Transform.register(SmevTransformSpi.ALGORITHM_URN, SmevTransformSpi.class.getName());
santuarioIgnoreLineBreaks(true);
LOGGER.log(Level.INFO, "SmevTransformSpi has been initialized");
} catch (AlgorithmAlreadyRegisteredException e) {
LOGGER.log(Level.INFO, "SmevTransformSpi Algorithm already registered: " e.getMessage());
}
Заодно сразу выполняем требование из Методических указаний:
Требования к форматированию В XML-структуре подписи между элементами не допускается наличие текстовых узлов, в том числе переводов строки.
santuarioIgnoreLineBreaks(true);
private static final String IGNORE_LINE_BREAKS_FIELD = "ignoreLineBreaks";
/**
* Apache Santuario privileged switch IgnoreLineBreaks property
*
* @param mode
*/
private void santuarioIgnoreLineBreaks(Boolean mode) {
try {
Boolean currMode = mode;
AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() {
public Boolean run() throws Exception {
Field f = XMLUtils.class.getDeclaredField(IGNORE_LINE_BREAKS_FIELD);
f.setAccessible(true);
f.set(null, currMode);
return false;
}
});
} catch (Exception e) {
LOGGER.warning("santuarioIgnoreLineBreaks " ExceptionUtils.getFullStackTrace(e));
}
}
Делается это в привилегированном блоке AccessController.doPrivileged
и через reflection, из-за особенности реализации свойства ignoreLineBreaks в Santuario.
Просто через настройку системного свойства:
System.setProperty("org.apache.xml.security.ignoreLineBreaks", "true");
не работает.
Через настройку опции JVM:
-Dcom.sun.org.apache.xml.internal.security.ignoreLineBreaks=true
работает.
Если взглянуть на код класса org.apache.xml.security.utils.XMLUtils, то можно увидеть, что поле ignoreLineBreaks статическое, инициализируется в привилегированном блоке из системного свойства «org.apache.xml.security.ignoreLineBreaks».
private static boolean ignoreLineBreaks =
AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return Boolean.valueOf(Boolean.getBoolean
("org.apache.xml.security.ignoreLineBreaks"));
}
}).booleanValue();
public static boolean ignoreLineBreaks() {
return ignoreLineBreaks;
}
Такая реализация приводит к невозможности гибко настроить в одном Java процессе для части методов игнорировать перевод строк, а для другой части не игнорировать.
Т.е., если одно приложение выполняет подписи XMLDsig, СМЭВ 2 и СМЭВ 3, все XML документы, обработанные Santuario должны на выходе лишиться перевода строк.
С этим свойством, конечно, возникает вопрос к Apache Santuario:
Подписать документ с помощью криптопро 5.0 — уц айтиком
В КриптоПРО версии 5.0 добавлена возможность подписывать документы электронной подписью с помощью утилиты Инструменты КриптоПро. Данная утилита входит в состав пакета установки КриптоПро 5.0, устанавливать отдельно ее не нужно.
Скачать КриптоПро 5.0 можно по ссылке.
Для подписания документа:
1. Откройте меню «Пуск», в списке программ найдите папку КРИПТО-ПРО, откройте её. Запустите приложение Инструменты КриптоПро.
2. Перейдите во вкладку «Создание подписи», нажмите на кнопку «Выбрать файл для подписи».
3. В открывшемся окне выберите файл, который необходимо подписать. Нажмите кнопку «Открыть».
4. Под кнопками «Выбрать файл для подписи» и «Сохранить подпись как» отобразится путь исходного файла и путь подписанного файла, который в дальнейшем будет создан.
Обратите внимание! По умолчанию КриптоПро 5.0 подписывает файлы в формате .p7s. Если требуется подписать файл в другом формате (к примеру, .sig), необходимо в конце пути будущего подписанного файла заменить .p7s на .sig. Поддерживаемые форматы: .p7s .sig .sgn |
По умолчанию подписанный документ сохраняется в той же папке, где находится исходный.
5. Выберите, какой электронной подписью необходимо подписать документ.
6. Нажмите кнопку «Подписать«. После завершения процесса подписания Вы увидите сообщение «Создание подписи завершилось успехом«, а так же в указанной директории будет создан файл с указанным расширением (.p7s / .sig / .sgn) – это и есть подписанный файл.
Обратите внимание! По умолчанию КриптоПро 5.0 создает присоединённую подпись. Если Вам необходимо создать отсоединённую подпись, перед подписанием (шаг 6) нажмите кнопку «Показать расширенные» и поставьте галочку «Создать отсоединённую подпись». |
Подписанный документ вы можете проверить с помощью нашей инструкции
Для того, чтобы работала система автоматического одобрения заявок на основании заявления, подписанного электронной подписью, нужно, чтобы в поле заявления был загружен файл, подписанный прикрепленной электронной подписью.
Вам необходимо предоставить подписанное квалифицированной ЭП заявление и подписанную доверенность (в случаях выпуска на сотрудника).
Для прикрепления данных документов, необходимо перейти в заявку на выпуск подписи и выбрать «Анкета и документы».
Внимание! Документы не принимаются в случае:
— Если они находятся в архиве.
— Если они имеют расширение отличающееся от .sig, .p7s, .sgn.
— Документ должен быть подписан прикрепленной подписью, открепленные подписи не принимаются.
В открывшемся окне необходимо выбрать раздел «Документы».
Далее необходимо загрузить документы в правильные поля.
Подписанное заявление загружается в поле:
Необходимо нажать на данное поле, откроется окно выбора необходимого документа, выберите подписанное заявление и нажмите «ОК», либо перетяните документ прямо на данную иконку.
Подписанная доверенность загружается в поле:
Необходимо нажать на данное поле, откроется окно выбора необходимого документа, выберите подписанное заявление и нажмите «ОК», либо перетяните документ прямо на данную иконку.
Подпись в html-форме
Такая задача возникает при встраивании средств ЭЦП в системах с «тонким» клиентом, когда пользователь работает в системе через Web-браузер (MS IE). В таких системах поступают следующим образом: создается скрытое hidden-поле в форме. Когда пользователь нажимает кнопку типа «подписать и отправить», соответствующий скрипт обработчика (например, на VBScript) формирует строковую переменную, в которую методом конкатенации записывают важную информацию по идентификации документа и содержимое текстовых полей, которые ввел пользователь.
Далее сформированная строковая переменная подписывается. Чаще всего используются методы объектов CAPICOM.dll, неотделенная подпись. Подписанная строковая переменная и есть электронный документ. Подписанный документ (подписанная строка) записывается в hidden-поле и методом POST передается на сервер.
Серверное приложение проверяет подпись в переменной, полученной из hidden-поля, и в зависимости от результатов проверки ЭЦП и содержательной части электронного документа осуществляет его дальнейшую обработку. Важным моментом является сохранение подписанного документа на сервере.
Подпись в базе данных
Довольно часто встречается нефайловая, или строковая, форма представления электронного документа, а электронный документ — как совокупность записей в таблицах базы данных. Для подписания такого документа значения полей записей в таблицах базы данных приводятся в строковый тип, и с помощью конкатенации формируется строковая переменная, отражающая существенную содержательную и идентификационную часть документа.
Именно эта строка теперь считается оригиналом электронного документа и подписывается. Подписанная строка сохраняется в соответствующей таблице базы данных системы с двумя полями: поле ключа документа и строковое поле, содержащее подписанный электронный документ.
Подпись документов в формате xml
Если документ представлен в формате XML, то имеется несколько подходов к формированию его подписей: формирование ЭЦП ХМL-документов XMLdsig для Windows (MSXML5, MSXML6) с использованием Microsoft Office InfoPath 2003 — новой составляющей системы Microsoft Office;
подпись XML-документа как обычного файла. Иногда для подписи в XML-документе в тэге документа создают отдельный атрибут, в который заносится ЭЦП от символьной строки переменной длины, содержащей значения атрибутов тэга документа. Такой достаточно интересный подход к подписи XML-документа также встречается, и он является вполне легитимным.
Подпись многофайловых документов
Иногда документ может представлять собой достаточно большую совокупность файлов. Например, сведения о первичных документах для совершения операций в реестре владельцев инвестиционных паев паевого фонда, полученных от управляющей компании. В этом случае можно формировать для каждого документа свою ЭЦП, а можно от этого отказаться.
Если по каким-либо причинам формирование ЭЦП для каждого файла документа невозможно, то создают еще один файл текстового формата, в который записывают идентификационные данные документа и значения хэш-функций для каждого файла документа. Именно этот файл (карточка документа) и подписывают.
Подпись сообщений смэв 3
Для подписи документов СМЭВ 3 все готово.
Код подписания выглядит следующим образом:
Проблемы. хэш не совпадает
Внимание!
Для отладки использовался пример конверта СМЭВ 3 SendRequestRequestNoAttach.xmlИз него был удален элемент ds:Signature с целью подписать сообщение заново и сверить с оригиналом.
Несмотря на то, что метод подписи и трансформация SmevTransformSpi, взятая из Методических указаний, отрабатывали, на выходе был подписанный документ, подпись которого при онлайн-проверке на портале СМЭВ 3 трактовалась как
ЭП-ОВ не подтверждена: Ошибка проверки ЭП: Нарушена целостность ЭП
Почему
не совпадал с оригинальным примером:
Для диагностики причин в класс SmevTransformSpi в метод process был добавлен свой XMLEventWriter.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XMLEventWriter bdst =
outputFactory.get().createXMLEventWriter(baos, ENCODING_UTF_8);
для параллельного анализа всех этапов трансформации.
Нормализованный элемент XML, на который требуется поставить подпись, выглядел следующим образом:
Поиск решения показал, что, во-первых
, нормализованный документ может выглядеть на самом деле иначе и соответственно его хэш будет другой и возможно правильный.
Во-вторых, привел в GitHub, где был выложен класс SmevTransformSpi более старой версии.
Старая версия класса трансформации выдала следующий нормализованный документ:
С ним хэш стал совпадать, а подпись успешно проходить валидацию.
Сравнение версий класса SmevTransformSpi показала, что помимо добавленных в новой реализации дополнительных функций логирования и диагностики в debug режиме:
if (logger.isDebugEnabled()) {
debugStream = new DebugOutputStream(argDst);
dst = outputFactory.get().createXMLEventWriter(debugStream, ENCODING_UTF_8);
} else {
dst = outputFactory.get().createXMLEventWriter(argDst, ENCODING_UTF_8);
}
Класс из Методических указаний не содержит нужную строчку, или содержит опечатку:
Отсутствует строка:
prefixMappingStack.pop();
, которая удаляет первый объект из стека с префиксами
Stack<List<Namespace>> prefixMappingStack = new Stack<List<Namespace>>();
, что приводило к неверной работе SmevTransformSpi.
Добавление этой строки в новую версию SmevTransformSpi.java решило проблему.
Проверка подписи сообщения смэв 3
Код проверки подписи выглядит следующим образом:
Результаты
Подписание конвертов СМЭВ 3 выполняется успешно.
Сообщения проходят проверку на портале Электронного правительства Госуслуги
И в собственном приложении: