Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Chemannnnn  
#1 Оставлено : 30 ноября 2021 г. 13:58:23(UTC)
Chemannnnn

Статус: Участник

Группы: Участники
Зарегистрирован: 29.11.2021(UTC)
Сообщений: 21

Сказал(а) «Спасибо»: 10 раз
Поблагодарили: 2 раз в 1 постах
Добрый день!
Прошу помощи в решении следующих задач:
1. С полученного XML со "встроенной" (прикреплённой) в него ЭЦП нужно снять электронную подпись, используя код Java. Подпись может находиться в начале (перед самим XML текстом) и в конце файла (после XML текста), а также фрагментами в середине XML, если файл довольно большого размера;
2. Получить только сами XML данные (т.е. только XML без электронной подписи).
Пример XML файла с подписью:

Подпись CMS/PKCS#7 в DER кодировке.
Алгоритм подписи: ГОСТ Р 34.10-2012
Загрузил с сайта архив "jcp-2.0.40035.zip" (КриптоПро JCP и JTLS R2 (2.0.40035)) и в нём нашёл "samples-sources.jar", но так и не понял какие именно примеры (классы) мне нужны для реализации этих задач.
Поискал похожие темы на форуме, почитал документацию, но разобраться так и не удалось. Насколько понял, сначала нужно верифицировать (проверить) подпись и если она проходит верификацию, то после этого можно изъять "чистый" XML (без самой подписи). Не понял, удаляется ли подпись из XML при верификации?
Если понимаю этот процесс НЕправильно, то прошу кратко описать шаги по снятию подписи с XML и дальнейшего получения XML без подписи.
А главное, прошу подсказать, какие именно примеры (из каких классов) мне нужно использовать, чтобы реализовать эту задачу на Java, используя JCP.
Заранее спасибо за ответы!

Отредактировано пользователем 30 ноября 2021 г. 17:25:40(UTC)  | Причина: Не указана

Offline Chemannnnn  
#2 Оставлено : 8 декабря 2021 г. 15:48:16(UTC)
Chemannnnn

Статус: Участник

Группы: Участники
Зарегистрирован: 29.11.2021(UTC)
Сообщений: 21

Сказал(а) «Спасибо»: 10 раз
Поблагодарили: 2 раз в 1 постах
Отвечу сам себе...
В скачанном с сайта архиве "jcp-2.0.40035.zip" в папке "javadoc" нашёл пример в "CAdES-javadoc.jar" (класс CAdESSignature, пример с использованием метода getSignedContent):

Для получения данных без подписи закомментировал строку №12 (сертификаты) и две последних строки - №35 (декодирование подписи) и №36 (проверка подписи). Код с этими закомментированными строками работает - "чистые" данные (без прикреплённой подписи PKCS7) из подписанного файла получается достать.

Но остались вопросы:
1. Для проверки подписи обязательно нужно декодировать её перед проверкой (верно ли понял, что декодируется она из base64)?
2. Для проверки (и декодирования) подписи нужны сертификаты? Т.е. строку №12 примера нужно раскомментировать и добавить множество сертификатов (или один корневой), а затем выполнить проверку подписи для этого множества сертификатов, верно?
3. Верно ли понимаю, что в "Контрольной панели" JCP на закладке "Хранилища ключей и сертификатов" нужно создать Хранилище сертификатов и добавить в него доверенный сертификат для проверки подписи?
И нужно ли на закладке "Алгоритмы" настроить тип провайдера и его параметры (параметры подписи в том числе) для работы с проверяемым типом подписи (или можно оставить там настройки по умолчанию)?

P.S. Пробовал выполнить c раскомментированными строками №35 и №36 (вместо сертификатов указал null) и получил следующие исключения:

Отредактировано пользователем 8 декабря 2021 г. 17:19:01(UTC)  | Причина: Не указана

Offline Санчир Момолдаев  
#3 Оставлено : 8 декабря 2021 г. 22:47:07(UTC)
Санчир Момолдаев

Статус: Сотрудник

Группы: Модератор, Участники
Зарегистрирован: 03.12.2018(UTC)
Сообщений: 1,040
Российская Федерация

Сказал(а) «Спасибо»: 88 раз
Поблагодарили: 226 раз в 213 постах
Добрый день!

Код:
        BufferedCAdESSignature bufferedCAdESSignature = new BufferedCAdESSignature(signToVerify, null, null);
        InputStream is = bufferedCAdESSignature.getSignedContent();
        byte[] dataFromSign = new byte[is.available()];
        is.read(dataFromSign);
        is.close();
        System.out.println(new String(dataFromSign, StandardCharsets.UTF_8));


то что вы указали в первом сообщении по всей видимости это DER представление ASN.1
это не Base64.

если у вас подпись base64, то ее необходимо перекодировать из base64 и подать в конструктор
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Санчир Момолдаев за этот пост.
Chemannnnn оставлено 16.12.2021(UTC)
Offline Евгений Афанасьев  
#4 Оставлено : 10 декабря 2021 г. 12:22:28(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,924
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 690 раз в 651 постах
Здравствуйте.
1-2. "С полученного XML со "встроенной" (прикреплённой) в него ЭЦП нужно снять электронную подпись" - судя по приложенному далее сообщению, наоборот, это XML в качестве подписанных данных в CMS подписи.
3. "сначала нужно верифицировать (проверить) подпись и если она проходит верификацию, то после этого можно изъять "чистый" XML (без самой подписи)." - не обязательно, данные находятся в верхней части подписи и могут быть извлечены, например, с помощью CAdESSignature или более низкоуровневых примеров из пакета CMS_samples архива samples-sources.jar, пример CMSVerify.
"Не понял, удаляется ли подпись из XML при верификации?" - не подпись из XML, а XML из подписи в качестве данных не удаляется.
4. "Для проверки подписи обязательно нужно декодировать её перед проверкой (верно ли понял, что декодируется она из base64)?" - если она в base64, то да, нужно из base64 в binary.
5. "Для проверки (и декодирования) подписи нужны сертификаты? Т.е. строку №12 примера нужно раскомментировать и добавить множество сертификатов (или один корневой), а затем выполнить проверку подписи для этого множества сертификатов, верно?" - сертификаты могут понадобиться для проверки, зависит от формата подписи. Если не ошибаюсь, извлечь данные можно не проверяя подпись.
6. "Верно ли понимаю, что в "Контрольной панели" JCP на закладке "Хранилища ключей и сертификатов" нужно создать Хранилище сертификатов и добавить в него доверенный сертификат для проверки подписи?
И нужно ли на закладке "Алгоритмы" настроить тип провайдера и его параметры (параметры подписи в том числе) для работы с проверяемым типом подписи (или можно оставить там настройки по умолчанию)?" - нет, корневые добавляются в cacerts. В "Алгоритмах" ничего настраивать не нужно.
7. "Пробовал выполнить c раскомментированными строками №35 и №36 (вместо сертификатов указал null) и получил следующие исключения" - вы строго задали проверить подпись, как CAdES-BES, но она не соответствует этому формату. Задайте null вместо CAdES-BES в CAdESSignature.
thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
Chemannnnn оставлено 16.12.2021(UTC)
Offline Chemannnnn  
#5 Оставлено : 10 декабря 2021 г. 17:22:26(UTC)
Chemannnnn

Статус: Участник

Группы: Участники
Зарегистрирован: 29.11.2021(UTC)
Сообщений: 21

Сказал(а) «Спасибо»: 10 раз
Поблагодарили: 2 раз в 1 постах
Здравствуйте. Благодарю за ответы. Немного разобравшись в терминах, почитав форум и исправив код получаю следующую ситуацию:
1. Из подписанного файла *.p7s с прикреплённой подписью (подпись в DER кодировке) с помощью "КриптоАРМ" получилось вытащить сертификат и загрузить его в доверенные JRE при помощи утилиты keytool (как это указано в руководстве программиста, приложенном к архиву с JCP):

При загрузке забыл указать параметр "-trustcacerts", но keytool спросил про это и я ответил утвердительно - сертификат был добавлен в хранилище как доверенный:

При листинге содержимого хранилища добавленный алиас сертификата отображается, отпечаток совпадает (проверил):

2. Исправил код, приведённый раннее в сообщении #2 (под верхним спойлером). Подписанные данные выгружаются в файл. Добавленный в хранилище сертификат тоже успешно вытаскивается из хранилища:

Но при проверке подписи этим сертификатом (в строке #55) выбрасывается исключение:

Строку #54 закомментировал, т.к. кодировка подписи DER (насколько понял, decode требуется при base64).
Дебагом проверял - из хранилища сертификатов вытаскивается именно загруженный сертификат (который был извлечён из подписанного файла).
3. Смущает сам сертификат, извлечённый из подписанного файла. Читал, что в хранилище сертификаты должны быть загружены в виде цепочки: корневой, промежуточный, сертификат подписи (могу ошибаться), как показано на скриншоте "Пути сертификации" в этом сообщении - ССЫЛКА
"Путь сертификации" извлечённого из подписанного файла сертификата выглядит так:

При этом проверка подписи в "КриптоАРМ" завершается ошибкой, в а подробной информации о подписи следующий текст:

В системе установлен сам JCP (в JRE) и "КриптоАРМ" для извлечения сертификата. КриптоПро CSP не установлен (он нужен?).

Отредактировано пользователем 10 декабря 2021 г. 17:56:25(UTC)  | Причина: Не указана

Offline Евгений Афанасьев  
#6 Оставлено : 10 декабря 2021 г. 18:37:54(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,924
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 690 раз в 651 постах
Автор: Chemannnnn Перейти к цитате
при проверке подписи этим сертификатом (в строке 55) выбрасывается исключение

Сначала надо вызвать decode, потом verify.
thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
Chemannnnn оставлено 16.12.2021(UTC)
Offline Chemannnnn  
#7 Оставлено : 10 декабря 2021 г. 19:24:25(UTC)
Chemannnnn

Статус: Участник

Группы: Участники
Зарегистрирован: 29.11.2021(UTC)
Сообщений: 21

Сказал(а) «Спасибо»: 10 раз
Поблагодарили: 2 раз в 1 постах
Раскомментировал строку кода #54 (decode) - она отрабатывает без ошибок. Но на строке кода #55 (verify) теперь выбрасывается следующее исключение:
Offline Евгений Афанасьев  
#8 Оставлено : 10 декабря 2021 г. 21:14:52(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,924
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 690 раз в 651 постах
Теперь ошибка о том, что не удается построить цепочку. Если корневой сертификат цепочки установлен в cacerts, то возможно, существует также промежуточный, который надо передать в verify.
thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
Chemannnnn оставлено 16.12.2021(UTC)
Offline Chemannnnn  
#9 Оставлено : 16 декабря 2021 г. 10:03:40(UTC)
Chemannnnn

Статус: Участник

Группы: Участники
Зарегистрирован: 29.11.2021(UTC)
Сообщений: 21

Сказал(а) «Спасибо»: 10 раз
Поблагодарили: 2 раз в 1 постах
Автор: Евгений Афанасьев Перейти к цитате
Теперь ошибка о том, что не удается построить цепочку. Если корневой сертификат цепочки установлен в cacerts, то возможно, существует также промежуточный, который надо передать в verify.

Ещё раз спасибо за помощь, разобрался.
Оказалось, что в хранилище доверенных сертификатов JRE (cacerts) добавил только пользовательский (личный) сертификат, который достал из подписи с помощью КриптоАРМ. Затем у этого сертификата на закладке "Состав" в поле "Доступ к информации о центрах сертификации" внизу нашёл URL к сертификату Удостоверяющего Центра (УЦ) и тоже добавил его в хранилище cacerts в качестве доверенного.
Причём работает даже вариант кода:

т.е. без передачи множества сертификатов в метод verify (JCP, видимо, сама проверяет наличие всей цепочки нужных сертификатов в хранилище).
Т.е. в моём случае, насколько я понял, для неквалифицированных сертификатов ЭП «цепочка доверия» может состоять только из двух звеньев: УЦ — пользователь. Поскольку квалифицированные сертификаты могут выдавать только аккредитованные УЦ, то в цепочке три звена: Минцифры — аккредитованный УЦ — пользователь.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.