Статус: Участник
Группы: Участники
Зарегистрирован: 29.11.2021(UTC) Сообщений: 21
Сказал(а) «Спасибо»: 10 раз Поблагодарили: 2 раз в 1 постах
|
Здравствуйте. Благодарю за ответы. Немного разобравшись в терминах, почитав форум и исправив код получаю следующую ситуацию: 1. Из подписанного файла *.p7s с прикреплённой подписью (подпись в DER кодировке) с помощью "КриптоАРМ" получилось вытащить сертификат и загрузить его в доверенные JRE при помощи утилиты keytool (как это указано в руководстве программиста, приложенном к архиву с JCP):
Код:keytool -import -alias nbchTest2021 -provider ru.CryptoPro.JCP.JCP -keystore "C:\Program Files\AdoptOpenJDK\jdk-8.0.232.09-openj9\jre\lib\security\cacerts" -storepass changeit -file c:\NbchRequest.cer
При загрузке забыл указать параметр "-trustcacerts", но keytool спросил про это и я ответил утвердительно - сертификат был добавлен в хранилище как доверенный:
Код:Trust this certificate? [no]: yes
Certificate was added to keystore
При листинге содержимого хранилища добавленный алиас сертификата отображается, отпечаток совпадает (проверил):
Код:keytool -list -keystore cacerts -storepass changeit
Код:nbchtest2021, 09.12.2021, trustedCertEntry,
Certificate fingerprint (SHA1): ...
2. Исправил код, приведённый раннее в сообщении #2 (под верхним спойлером). Подписанные данные выгружаются в файл. Добавленный в хранилище сертификат тоже успешно вытаскивается из хранилища:
Код: System.setProperty("com.sun.security.enableCRLDP", "true");
System.setProperty("com.ibm.security.enableCRLDP", "true");
// Исходная CAdES-BES подпись в виде потока байтов из файла.
FileInputStream cadesCms = new FileInputStream("NbchRequest.p7s");
// Сертификаты для проверки подписи.
Set<X509Certificate> certs = new LinkedHashSet<>();
certs.clear();
// читаем сертификаты из cacerts
String pathToKeyStore = System.getProperty("java.home") + File.separatorChar + "lib" + File.separatorChar + "security" + File.separatorChar + "cacerts";
char[] keyStorePassword = "changeit".toCharArray();
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(pathToKeyStore), keyStorePassword);
Enumeration<String> alias = keyStore.aliases();
Map<String, X509Certificate> cacerts = new LinkedHashMap<>();
while (alias.hasMoreElements()) {
X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias.nextElement());
Vector values = PrincipalUtil.getSubjectX509Principal(certificate).getValues(X509Name.CN);
if (values.size() > 0) {
cacerts.put((String) values.get(0), certificate);
}
}
//добавляем корневые сертификаты
certs.add(cacerts.get("СГКО НБКИ ТЕСТ 2021"));
// Откладываем декодирование, извлекаем подписанные
// данные, декодируем и проверяем совмещенную CAdES-BES подпись.
CAdESSignature cadesSignature = new CAdESSignature(cadesCms, null, null, false, true); // откладываем декодирование, передав последним параметром userDecode = true
InputStream contentStream = cadesSignature.getSignedContent(); // поток подписанных данных (контент)
if (contentStream != null) { // если подпись отделенная, то contentStream == null
final int size = 16 * 1024 * 1024;
byte[] buffer = new byte[size];
int read;
FileOutputStream fileContentStream = new FileOutputStream("content.xml"); // файл для сохранения контента
while ((read = contentStream.read(buffer, 0, size)) > 0) {
fileContentStream.write(buffer, 0, read);
} // while
fileContentStream.close();
}
// cadesSignature.decode(); // самостоятельно вызываем декодирование подписи
cadesSignature.verify(certs); // проверка, если необходима
Но при проверке подписи этим сертификатом (в строке #55) выбрасывается исключение:
Код:Exception in thread "main" Signers not found; error codes: [8] 'Signature is invalid',
at ru.CryptoPro.CAdES.cl_1.verify(Unknown Source)
Строку #54 закомментировал, т.к. кодировка подписи DER (насколько понял, decode требуется при base64). Дебагом проверял - из хранилища сертификатов вытаскивается именно загруженный сертификат (который был извлечён из подписанного файла). 3. Смущает сам сертификат, извлечённый из подписанного файла. Читал, что в хранилище сертификаты должны быть загружены в виде цепочки: корневой, промежуточный, сертификат подписи (могу ошибаться), как показано на скриншоте "Пути сертификации" в этом сообщении - ССЫЛКА"Путь сертификации" извлечённого из подписанного файла сертификата выглядит так:
cert_path.jpg (37kb) загружен 4 раз(а).
При этом проверка подписи в "КриптоАРМ" завершается ошибкой, в а подробной информации о подписи следующий текст:
Код:Параметры подписи Подписи
Статус Общий статус подписи Одна или несколько подписей некорректна или нет доверия
Статус проверки математической корректности Одна или несколько подписей некорректна или нет доверия
Статус проверки сертификата Невозможно построить цепочку для сертификата
В системе установлен сам JCP (в JRE) и "КриптоАРМ" для извлечения сертификата. КриптоПро CSP не установлен (он нужен?). Отредактировано пользователем 10 декабря 2021 г. 17:56:25(UTC)
| Причина: Не указана
|