Статус: Активный участник
Группы: Участники
Зарегистрирован: 05.08.2019(UTC) Сообщений: 65
Сказал(а) «Спасибо»: 4 раз
|
Добрый день! Реализовал создание открепленной PKCS#7 подписи при помощи КриптоПро JCP Однако, есть проблема: В используемом методе (из jarника samples) агрументом является объект X509Certficiate (т.е. подписанта). Соответственно, в подпись включается только он. Используемый метод: Цитата: /** * Функция формирования простой отсоединенной подписи формата PKCS#7 * по хешу сообщения. * Пример подписи взят из {@link CMS_samples.CMS#CMSSign(byte[], * PrivateKey, Certificate, boolean)}. * * @param data Данные для подписи. * @param privateKey Закрытый ключ для создания ЭЦП. * @param certificate Сертификат подписи. * @return ЭЦП. * @throws Exception */ public static byte[] createPKCS7(byte[] data, PrivateKey privateKey, X509Certificate certificate) throws Exception {
// Получаем бинарную подпись длиной 64 байта.
final Signature signature = Signature.getInstance(AlgorithmUtils.getSignatureInstanceForJCP(certificate)); //hardcoded JCP.GOST_DHEL_SIGN_NAME signature.initSign(privateKey); signature.update(data);
final byte[] sign = signature.sign();
// Формируем контекст подписи формата PKCS7.
final ContentInfo all = new ContentInfo(); all.contentType = new Asn1ObjectIdentifier( new OID(CMStools.STR_CMS_OID_SIGNED).value);
final SignedData cms = new SignedData(); all.content = cms; cms.version = new CMSVersion(1);
// Идентификатор алгоритма хеширования.
String [] digestAndSignatureAlgorithms = AlgorithmUtils.getDigestSignatureAlgorithmOIDs(certificate);
cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1); final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier( new OID(digestAndSignatureAlgorithms[0]).value); //hardcoded CMStools.DIGEST_OID a.parameters = new Asn1Null(); cms.digestAlgorithms.elements[0] = a;
// Т.к. подпись отсоединенная, то содержимое отсутствует.
cms.encapContentInfo = new EncapsulatedContentInfo( new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_DATA).value), null);
// Добавляем сертификат подписи.
cms.certificates = new CertificateSet(1); final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate asnCertificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
final Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(certificate.getEncoded()); asnCertificate.decode(decodeBuffer);
cms.certificates.elements = new CertificateChoices[1]; cms.certificates.elements[0] = new CertificateChoices(); cms.certificates.elements[0].set_certificate(asnCertificate);
// Добавялем информацию о подписанте.
cms.signerInfos = new SignerInfos(1); cms.signerInfos.elements[0] = new SignerInfo(); cms.signerInfos.elements[0].version = new CMSVersion(1); cms.signerInfos.elements[0].sid = new SignerIdentifier();
final byte[] encodedName = certificate.getIssuerX500Principal().getEncoded(); final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName); final Name name = new Name(); name.decode(nameBuf);
final CertificateSerialNumber num = new CertificateSerialNumber( certificate.getSerialNumber());
cms.signerInfos.elements[0].sid.set_issuerAndSerialNumber( new IssuerAndSerialNumber(name, num)); cms.signerInfos.elements[0].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(digestAndSignatureAlgorithms[0]).value); // hardcoded CMStools.DIGEST_OID cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null(); cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(digestAndSignatureAlgorithms[1]).value); //hardcoded CMStools.SIGN_OID cms.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null(); cms.signerInfos.elements[0].signature = new SignatureValue(sign);
// Получаем закодированную подпись.
final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer(); all.encode(asnBuf, true);
return asnBuf.getMsgCopy(); } В связи с этим у меня есть вопросы: Как включить всю цепочку в подпись? Откуда ее можно взять, если в контейнере у данного сертификата ее нет? Откуда цепочка вообще берется? Заранее спасибо.
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602  Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Автор: rmussalimov  Как включить всю цепочку в подпись? Откуда ее можно взять, если в контейнере у данного сертификата ее нет?
Добрый день. Полагаю цепочку надо добавлять в cms.certificates.elements. Как получить исчерпывающая инструкция буквально на странице 2 данного раздела форума https://www.cryptopro.ru...aspx?g=posts&t=16695Еще почти тоже: https://www.cryptopro.ru...&m=107822#post107822Автор: rmussalimov  Откуда цепочка вообще берется? Вручную для построения цепочки можно зайти на e-trust.gosuslugi.ru и поискать сертификат УЦ выдавшего Ваш сертификат, алгоритм такой: 1. открываете сертификат (в начале свой, если перешли с шага 4, то скачанный сертификат УЦ) смотрите поле издатель - из него интересует огрн издателя, смотрите поле идентификатор ключа ЦС (тут интересуют только шестнадцатеричные цифры). 2. Если это не Минкомсвязь/головной удостоверяющий центр на сайте e-trust.gosuslugi.ru в меню переходите в аккредитованные УЦ, вводите огрн в поле фильтра, нажимаете найти, найдется один пункт, надо нажать лупу слева от названия УЦ. Если Минкомсвязь/головной удостоверяющий центр, то нужно на сайте в меню выбрать головной УЦ. 3. на странице УЦ находите соотвествующий сертификат по идентификатору ключа, скачиваете. 4. открываете сертификат УЦ, если это не Минкомсвязь/головной удостоверяющий центр - переходите к шагу 1, если Минкомсвязь/головной удостоверяющий центр - убеждаетесь что идентификатор ключа субъекта равен идентификатору ключа ЦС. Если равен, то это корневой сертификат и конец алгоритма, если не равен - переходите к шагу 1. Программно все практически так же, но берется адрес из расширения сертификата сведения о ЦС - в котором указаны прямые адреса где лежит сертификат УЦ (не e-trust.gosuslugi.ru, а на сайте УЦ). Адрес может быть недоступен или отключено докачивание сертификатов цепочки или отключен Интернет - тогда цепочка не построится автоматически. Отредактировано пользователем 22 октября 2019 г. 10:54:33(UTC)
| Причина: Не указана
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 05.08.2019(UTC) Сообщений: 65
Сказал(а) «Спасибо»: 4 раз
|
Автор: two_oceans  Автор: rmussalimov  Как включить всю цепочку в подпись? Откуда ее можно взять, если в контейнере у данного сертификата ее нет?
Добрый день. Полагаю цепочку надо добавлять в cms.certificates.elements. Как получить исчерпывающая инструкция буквально на странице 2 данного раздела форума https://www.cryptopro.ru...aspx?g=posts&t=16695Еще почти тоже: https://www.cryptopro.ru...&m=107822#post107822Автор: rmussalimov  Откуда цепочка вообще берется? Вручную для построения цепочки можно зайти на e-trust.gosuslugi.ru и поискать сертификат УЦ выдавшего Ваш сертификат, алгоритм такой: 1. открываете сертификат (в начале свой, если перешли с шага 4, то скачанный сертификат УЦ) смотрите поле издатель - из него интересует огрн издателя, смотрите поле идентификатор ключа ЦС (тут интересуют только шестнадцатеричные цифры). 2. Если это не Минкомсвязь/головной удостоверяющий центр на сайте e-trust.gosuslugi.ru в меню переходите в аккредитованные УЦ, вводите огрн в поле фильтра, нажимаете найти, найдется один пункт, надо нажать лупу слева от названия УЦ. Если Минкомсвязь/головной удостоверяющий центр, то нужно на сайте в меню выбрать головной УЦ. 3. на странице УЦ находите соотвествующий сертификат по идентификатору ключа, скачиваете. 4. открываете сертификат УЦ, если это не Минкомсвязь/головной удостоверяющий центр - переходите к шагу 1, если Минкомсвязь/головной удостоверяющий центр - убеждаетесь что идентификатор ключа субъекта равен идентификатору ключа ЦС. Если равен, то это корневой сертификат и конец алгоритма, если не равен - переходите к шагу 1. Программно все практически так же, но берется адрес из расширения сертификата сведения о ЦС - в котором указаны прямые адреса где лежит сертификат УЦ (не e-trust.gosuslugi.ru, а на сайте УЦ). Адрес может быть недоступен или отключено докачивание сертификатов цепочки или отключен Интернет - тогда цепочка не построится автоматически. Спасибо за ответ. Допустим, все сертификаты были скачаны, как определяется, что X сертификат выдан сертификат Y, который выдал сертификат Z (конечный)? После этого в хранилище криптопро csp сертификаты будут связаны цепочкой? Т.е я смогу вызвать keyStore.getCertificateChain(String alias), и это вернет мне всю цепочку? Далее будет ли возможно просто добавить в цикле cms.certificates полученную цепочку?
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 4,006  Откуда: Крипто-Про Сказал(а) «Спасибо»: 21 раз Поблагодарили: 715 раз в 675 постах
|
Здравствуйте. В samples-sources.jar в дистрибутиве в пакете userSamples есть примеры построения (и проверки) цепочки сертификатов CRLValidateCert (по CRL) и OCSPValidateCert (по OCSP или CRL) от target-сертификата (EE) до корневого, который должен быть в списке TrustAnchor. Дополнительные сертификаты (промежуточные) могут быть добавлены в addCertStore. CRLValidateCert с помощью enableAIAcaIssuers может догрузить промежуточные сертификаты из сети, если ссылки на них есть в сертификатов. |
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602  Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Автор: rmussalimov  Допустим, все сертификаты были скачаны... После этого в хранилище криптопро csp сертификаты будут связаны цепочкой? Добрый день. Отвечу в общем, без конкретики для Джавы. Если просто скачать, то эффекта никакого, нужно установить в хранилище корневых/промежуточных сертификатов. Информация о цепочке не сохраняется в хранилище и строится каждый раз, но приложение может на некоторое время "закэшировать" цепочку и статус сертификатов. Делает ли кэширование Джава точно сказать не могу, скорее нет (то есть проверка проводится каждый раз снова). Для Джавы корневой должен быть в списке TrustAnchor. Автор: rmussalimov  как определяется, что X сертификат выдан сертификат Y, который выдал сертификат Z (конечный)? Это наверно один из самых нестабильных вопросов отечественной криптографии. Самый надежный способ определять цепочку - по идентификатору ключа, как в сообщении выше. Для аккредитованных отечественных УЦ идентификатор ключа всегда присутствует. Однако, зарубежные стандарты указывают идентификатор ключа как необязательное расширение сертификата (во многих зарубежных сертификатах оно отсутствует), то есть механизмы встроенные в ОС (скажу за Windows) не полагаются на идентификатор ключа и не особенно гибко ищут по полям Субъект - Издатель, которые обязательные (предпочтение отдается элементу CN (если есть - в большинстве случаев есть) потом E (если есть E и нет CN) и так далее).
Из-за такой методики иногда возникают накладки с построением цепочки когда у российского УЦ есть два сертификата (зарубежные часто используют политику одному владельцу - один сертификат и если УЦ выпускает новый сертификат старый сертификат данного УЦ аннулируют, есть даже механизм подхвата клиентов со старого сертификата УЦ), причем два сертификата с одинаковым именем (чаще всего разного года выпуска) и в системе установлен "не тот" (например, нужен сертификат УЦ "Тензор" 2017 года, а установлен в системе 2016 года). В этом случае процедура построения цепочки может не сверить идентификатор ключа и не сверить какой сертификат скачивается по адресу в клиентском сертификате, а просто взять "не тот" сертификат УЦ из хранилища по имени УЦ и объявить "конечный сертификат изменен, цепочка не верна". Приходится это решать установкой правильного параллельно (построится две цепочки, одна отбракуется, 50 на 50 что выберется "не та"), а иногда и удалением "не того" (если выбралась "не та", оставляем только верную цепочку). Этой проблемы просто не возникает если использовать идентификатор ключа (он фактически уникальный - вариантов хэша sha-1 ключа (160 бит) гораздо больше чем адресов ipv6 или guid (128 бит)).
Также есть проблемы в случае когда промежуточный сертификат установлен в корневое хранилище (или в TrustAnchor) - в этом случае получится две действительных цепочки и не факт, что выберется правильная. Теоретически обе должны приниматься, но на практике выбирается короткая и бывает баг что она отбраковывается. То есть минус в том что цепочка сначала выбирается самая короткая из всех потом проверяется только она, а не так что проверяются все цепочки и самая короткая из прошедших проверку выбирается.
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 05.08.2019(UTC) Сообщений: 65
Сказал(а) «Спасибо»: 4 раз
|
Автор: Евгений Афанасьев  Здравствуйте. В samples-sources.jar в дистрибутиве в пакете userSamples есть примеры построения (и проверки) цепочки сертификатов CRLValidateCert (по CRL) и OCSPValidateCert (по OCSP или CRL) от target-сертификата (EE) до корневого, который должен быть в списке TrustAnchor. Дополнительные сертификаты (промежуточные) могут быть добавлены в addCertStore. CRLValidateCert с помощью enableAIAcaIssuers может догрузить промежуточные сертификаты из сети, если ссылки на них есть в сертификатов. Хорошо, можете тогда подсказать, пожалуйста, как будет выглядеть метод, который вместо X509Certificate будет принимать Certificate [] (массив сертификатов). Сейчас в подпись сертификаты добавляются так. Цитата: // Добавляем сертификат подписи.
cms.certificates = new CertificateSet(1); final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate asnCertificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
final Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(certificate.getEncoded()); asnCertificate.decode(decodeBuffer);
cms.certificates.elements = new CertificateChoices[1]; cms.certificates.elements[0] = new CertificateChoices(); cms.certificates.elements[0].set_certificate(asnCertificate); Насколько понимаю, должен быть цикл. Думаю, метод должен выглядеть так (массив сертификатов allCerts). 0-ой серт, это серт подписанта. Цитата: // Добавляем сертификатЫ подписи.
cms.certificates = new CertificateSet(allCerts.length); cms.certificates.elements = new CertificateChoices[allCerts.length];
for(int i = 0; i < allCerts.length; i++) { final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate asnCertificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
final Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(allCerts[i].getEncoded()); asnCertificate.decode(decodeBuffer);
cms.certificates.elements[i] = new CertificateChoices(); cms.certificates.elements[i].set_certificate(asnCertificate); }
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 05.08.2019(UTC) Сообщений: 65
Сказал(а) «Спасибо»: 4 раз
|
Автор: Евгений Афанасьев  Здравствуйте. В samples-sources.jar в дистрибутиве в пакете userSamples есть примеры построения (и проверки) цепочки сертификатов CRLValidateCert (по CRL) и OCSPValidateCert (по OCSP или CRL) от target-сертификата (EE) до корневого, который должен быть в списке TrustAnchor. Дополнительные сертификаты (промежуточные) могут быть добавлены в addCertStore. CRLValidateCert с помощью enableAIAcaIssuers может догрузить промежуточные сертификаты из сети, если ссылки на них есть в сертификатов. Как конкретно называется метод, который строит цепочку?
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 4,006  Откуда: Крипто-Про Сказал(а) «Спасибо»: 21 раз Поблагодарили: 715 раз в 675 постах
|
Метод build класса CertPathBuilder, алгоритм и провайдер - "CPPKIX" и "RevCheck":
PKIXCertPathBuilderResult res = (PKIXCertPathBuilderResult) CertPathBuilder.getInstance("CPPKIX", "RevCheck").build(cpp); cpp - параметры класса PKIXBuilderParameters, куда можно передать: сертификат, для которого строится цепочка, дополнительные хранилища для поиска сертификатов при построении, дату, список доверенных корневых (TrustAnchor) и т.д. |
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 05.08.2019(UTC) Сообщений: 65
Сказал(а) «Спасибо»: 4 раз
|
Автор: Евгений Афанасьев  Метод build класса CertPathBuilder, алгоритм и провайдер - "CPPKIX" и "RevCheck":
PKIXCertPathBuilderResult res = (PKIXCertPathBuilderResult) CertPathBuilder.getInstance("CPPKIX", "RevCheck").build(cpp); cpp - параметры класса PKIXBuilderParameters, куда можно передать: сертификат, для которого строится цепочка, дополнительные хранилища для поиска сертификатов при построении, дату, список доверенных корневых (TrustAnchor) и т.д. Спасибо большое. Последний вопрос - данным методом цепочка строится локально? В нашем сертификате есть информация о промежуточном, только по URL он недоступен.
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 4,006  Откуда: Крипто-Про Сказал(а) «Спасибо»: 21 раз Поблагодарили: 715 раз в 675 постах
|
Да, строится на вашем компьютере. В сертификате может быть информация о сертификате УЦ, например, в клиентском сертификате ссылка на промежуточный, а может не быть, ссылка может быть рабочая, а может не работать. В любом случае промежуточный должен быть каким-то образом достижим: либо скачан отдельно (в виде файла) и передан в параметр cpp перед build, либо не скачан, но доступен по ссылке в предыдущем сертификате при включенном параметре enableAIAcaIssuers. Надежнее, пожалуй, скачать/закешировать промежуточный. Кстати, keyStore.getCertificateChain() вернет список сертификатов (цепочку) из ключевого контейнера, только если цепочка была туда установлена (такое бывает нечасто). Отредактировано пользователем 23 октября 2019 г. 15:44:24(UTC)
| Причина: Не указана |
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close