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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline miser  
#1 Оставлено : 18 июля 2018 г. 14:56:31(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 14.03.2011(UTC)
Сообщений: 153
Мужчина
Откуда: Санкт-Петербург

Сказал «Спасибо»: 1 раз
Поблагодарили: 7 раз в 5 постах
Добрый день. Ошибка проверки корневого сертификата
Код:

  <ПрограммноАппаратныйКомплекс>
    <Псевдоним>Минкомсвязь России</Псевдоним>
    <КлассСредствЭП>КВ2</КлассСредствЭП>
    <Адрес>
      <Страна>RU</Страна>
      <Регион>
        <Код>77</Код>
        <Название>Москва</Название>
      </Регион>
      <Индекс>125375</Индекс>
      <УлицаДом>ул. Тверская, д. 7</УлицаДом>
      <Город>Москва</Город>
    </Адрес>
    <СредстваУЦ>ПАК «Головной УЦ»</СредстваУЦ>
    <КлючиУполномоченныхЛиц>
      <Ключ>
        <ИдентификаторКлюча>C254F1B46BD44CB7E06D36B42390F1FEC33C9B06</ИдентификаторКлюча>
        <АдресаСписковОтзыва>
          <Адрес>http://reestr-pki.ru/cdp/guc_gost12.crl</Адрес>
          <Адрес>http://company.rt.ru/cdp/guc_gost12.crl</Адрес>
          <Адрес>http://rostelecom.ru/cdp/guc_gost12.crl</Адрес>
        </АдресаСписковОтзыва>
        <Сертификаты>
          <ДанныеСертификата>
            <Отпечаток>4BC6DC14D97010C41A26E058AD851F81C842415A</Отпечаток>
            <КемВыдан>CN=Минкомсвязь России, ИНН=007710474375, ОГРН=1047702026701, O=Минкомсвязь России, STREET="улица Тверская, дом 7", L=г. Москва, S=77 Москва, C=RU, E=dit@minsvyaz.ru</КемВыдан>
            <КомуВыдан>CN=Минкомсвязь России, ИНН=007710474375, ОГРН=1047702026701, O=Минкомсвязь России, STREET="улица Тверская, дом 7", L=г. Москва, S=77 Москва, C=RU, E=dit@minsvyaz.ru</КомуВыдан>
            <СерийныйНомер>4E6D478B26F27D657F768E025CE3D393</СерийныйНомер>
            <ПериодДействияС>2018-07-06T12:18:06Z</ПериодДействияС>
            <ПериодДействияДо>2036-07-01T12:18:06Z</ПериодДействияДо>
            <Данные>MIIFFDCCBMGgAwIBAgIQTm1HiybyfWV/do4CXOPTkzAKBggqhQMHAQEDAjCCASQxHjAcBgkqhkiG9w0BCQEWD2RpdEBtaW5zdnlhei5ydTELMAkGA1UEBhMCUlUxGDAWBgNVBAgMDzc3INCc0L7RgdC60LLQsDEZMBcGA1UEBwwQ0LMuINCc0L7RgdC60LLQsDEuMCwGA1UECQwl0YPQu9C40YbQsCDQotCy0LXRgNGB0LrQsNGPLCDQtNC+0LwgNzEsMCoGA1UECgwj0JzQuNC90LrQvtC80YHQstGP0LfRjCDQoNC+0YHRgdC40LgxGDAWBgUqhQNkARINMTA0NzcwMjAyNjcwMTEaMBgGCCqFAwOBAwEBEgwwMDc3MTA0NzQzNzUxLDAqBgNVBAMMI9Cc0LjQvdC60L7QvNGB0LLRj9C30Ywg0KDQvtGB0YHQuNC4MB4XDTE4MDcwNjEyMTgwNloXDTM2MDcwMTEyMTgwNlowggEkMR4wHAYJKoZIhvcNAQkBFg9kaXRAbWluc3Z5YXoucnUxCzAJBgNVBAYTAlJVMRgwFgYDVQQIDA83NyDQnNC+0YHQutCy0LAxGTAXBgNVBAcMENCzLiDQnNC+0YHQutCy0LAxLjAsBgNVBAkMJdGD0LvQuNGG0LAg0KLQstC10YDRgdC60LDRjywg0LTQvtC8IDcxLDAqBgNVBAoMI9Cc0LjQvdC60L7QvNGB0LLRj9C30Ywg0KDQvtGB0YHQuNC4MRgwFgYFKoUDZAESDTEwNDc3MDIwMjY3MDExGjAYBggqhQMDgQMBARIMMDA3NzEwNDc0Mzc1MSwwKgYDVQQDDCPQnNC40L3QutC+0LzRgdCy0Y/Qt9GMINCg0L7RgdGB0LjQuDBmMB8GCCqFAwcBAQEBMBMGByqFAwICIwEGCCqFAwcBAQICA0MABEB1OSpFp7milX33EP0ikge6HbZacYp9fVj8sUa5RWFXrB27SKX5SvtIGepqKev69RSYeHHKR+jT9YX2NuSK9wONo4IBwjCCAb4wgfUGBSqFA2RwBIHrMIHoDDTQn9CQ0JrQnCDCq9Ca0YDQuNC/0YLQvtCf0YDQviBIU03CuyDQstC10YDRgdC40LggMi4wDEPQn9CQ0JogwqvQk9C+0LvQvtCy0L3QvtC5INGD0LTQvtGB0YLQvtCy0LXRgNGP0Y7RidC40Lkg0YbQtdC90YLRgMK7DDXQl9Cw0LrQu9GO0YfQtdC90LjQtSDihJYgMTQ5LzMvMi8yLzIzINC+0YIgMDIuMDMuMjAxOAw00JfQsNC60LvRjtGH0LXQvdC40LUg4oSWIDE0OS83LzYvMTA1INC+0YIgMjcuMDYuMjAxODA/BgUqhQNkbwQ2DDTQn9CQ0JrQnCDCq9Ca0YDQuNC/0YLQvtCf0YDQviBIU03CuyDQstC10YDRgdC40LggMi4wMEMGA1UdIAQ8MDowCAYGKoUDZHEBMAgGBiqFA2RxAjAIBgYqhQNkcQMwCAYGKoUDZHEEMAgGBiqFA2RxBTAGBgRVHSAAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTCVPG0a9RMt+BtNrQjkPH+wzybBjAKBggqhQMHAQEDAgNBAJr6/eI7rHL7+FsQnoH2i6DVxqalbIxLKj05edpZGPLLb6B2PTAMya7pSt9hb8QnFABgsR4IE5gT4VVkDWbX/n4=</Данные>
          </ДанныеСертификата>
        </Сертификаты>
      </Ключ>
    </КлючиУполномоченныхЛиц>
  </ПрограммноАппаратныйКомплекс>      

Выполняю не хитрый код
Код:

PublicKey key = cert.getPublicKey();
cert.verify(key);

Получаю ошибку
Цитата:

java.lang.NullPointerException
at ru.CryptoPro.JCP.Sign.cl_0.engineInitVerify(Unknown Source)
at java.security.Signature.initVerify(Signature.java:460)
at org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject.checkSignature(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject.verify(Unknown Source)


Пробовал последнюю версию JCP 2.0.39738
При этом, все остальные ключи, указанные в реестре аккредитованных УЦ, со старыми ГОСТ, эту проверку проходят.
Offline Евгений Афанасьев  
#2 Оставлено : 18 июля 2018 г. 15:24:20(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 715 раз в 675 постах
Здравствуйте.
Проверим. Я бы предположил, что key == null. И выполняется проверка у сертификата org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject (возможно, там есть нюансы).

Отредактировано пользователем 18 июля 2018 г. 15:25:37(UTC)  | Причина: Не указана

Offline Евгений Афанасьев  
#3 Оставлено : 18 июля 2018 г. 15:45:52(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 715 раз в 675 постах
Вероятно, причина в этом - X509CertificateObject:
Код:

public PublicKey getPublicKey()
    {
        try
        {
            return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo());
        }
        catch (IOException e)
        {
            return null;   // should never happen...
        }
    }

public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo) // класс BouncyCastleProvider 
        throws IOException
    {
        AsymmetricKeyInfoConverter converter = (AsymmetricKeyInfoConverter)keyInfoConverters.get(publicKeyInfo.getAlgorithm().getAlgorithm()); // <--

        if (converter == null)
        {
            return null;
        }

        return converter.generatePublic(publicKeyInfo);
    }


А со старым ГОСТом работает, т.к. его алгоритм есть в BC.
У BouncyCastleProvider есть список keyInfoConverters, его можно дополнить с помощью addKeyInfoConverter(). Наверно, можно подкрутить и сделать так, чтобы выбирался нужный конвертор и конвертил блоб ключа так, чтобы getPublicKey возвращал ключ. AsymmetricKeyInfoConverter будет что-то типа KeyFactory.

Отредактировано пользователем 18 июля 2018 г. 15:49:55(UTC)  | Причина: Не указана

Offline miser  
#4 Оставлено : 18 июля 2018 г. 15:55:30(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 14.03.2011(UTC)
Сообщений: 153
Мужчина
Откуда: Санкт-Петербург

Сказал «Спасибо»: 1 раз
Поблагодарили: 7 раз в 5 постах
Действительно, код возвращает null.
Код:
PublicKey key = cert.getPublicKey();

Но как, такое возможно? Это же блок с фиксированным OID.
Может, в BouncyCastle надо прописать OID ключа подписи. Сейчас, там есть ECGOST3410 (AsymmetricKeyInfoConverter).

Как-то туманно, распознавать самому все эти OID и перечитывать сертификаты тем или иным провайдером. Мне, например, удобен функционал замены OID ИНН, КПП в сведениях владельца. BouncyCastle делает это красиво.
BouncyCastle пишет компоненты сведений владельца в одном порядке, CryptoPro, в другом порядке.

Отредактировано пользователем 18 июля 2018 г. 15:59:13(UTC)  | Причина: Не указана

Offline Евгений Афанасьев  
#5 Оставлено : 18 июля 2018 г. 16:12:13(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 715 раз в 675 постах
Автор: miser Перейти к цитате
Может, в BouncyCastle надо прописать OID ключа подписи. Сейчас, там есть ECGOST3410 (AsymmetricKeyInfoConverter).

Да, вероятно, это можно сделать с помощью addKeyInfoConverter в классе BouncyCastleProvider. Прописать, полагаю, надо 2 OID'а - 1.2.643.7.1.1.1.1 и .2.643.7.1.1.1.2. Наверно, где-то делается что-то типа Certificate cert = CertificateFactory.getInstance("X.509", "BC").generateCertificate(...) с указанием провайдера, в итоге получаем X509CertificateObject. Оракловая версия X.509, конечно, отличается от BC.
Offline miser  
#6 Оставлено : 18 июля 2018 г. 16:28:20(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 14.03.2011(UTC)
Сообщений: 153
Мужчина
Откуда: Санкт-Петербург

Сказал «Спасибо»: 1 раз
Поблагодарили: 7 раз в 5 постах
Спасибо. Попробую пошаманить.

Думаю, у меня главная проблема будет вот тут:
Код:

Set<X509Certificate> intermediateCerts = ...

// Specify a list of intermediate certificates
CertStore intermediateCertStore = CertStore.getInstance("Collection",
    new CollectionCertStoreParameters(intermediateCerts), "BC");
pkixParams.addCertStore(intermediateCertStore);


// Build and verify the certification chain
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC");
PKIXCertPathBuilderResult result =
    (PKIXCertPathBuilderResult) builder.build(pkixParams);

Он ведь где-то глубоко внутри будет делать примерно то же самое.
Offline Евгений Афанасьев  
#7 Оставлено : 18 июля 2018 г. 16:33:01(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 715 раз в 675 постах
Вот:
Код:

class GostConvertor implements AsymmetricKeyInfoConverter {

            private final KeyFactory factory;

            public GostConvertor() {

                try {
                    factory = KeyFactory.getInstance(JCP.GOST_EL_DEGREE_NAME);
                } catch (NoSuchAlgorithmException e) {
                    throw new RuntimeException(e);
                }

            }

            @Override
            public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) throws IOException {
                return null;
            }

            @Override
            public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) throws IOException {

                byte[] key = keyInfo.getEncoded();
                X509EncodedKeySpec spec = new X509EncodedKeySpec(key);

                try {
                    return factory.generatePublic(spec);
                } catch (InvalidKeySpecException e) {
                    throw new IOException(e);
                }

            }
        }

        BouncyCastleProvider bc = new BouncyCastleProvider();

        bc.addKeyInfoConverter(new ASN1ObjectIdentifier(JCP.GOST_PARAMS_SIG_2012_256_KEY_OID), new GostConvertor());
        bc.addKeyInfoConverter(new ASN1ObjectIdentifier(JCP.GOST_PARAMS_SIG_2012_512_KEY_OID), new GostConvertor());

        Security.addProvider(bc);
        Certificate cert = CertificateFactory.getInstance("X.509", "BC").generateCertificate(new ByteArrayInputStream(decoded)); // decoded - ваш сертификат

        PublicKey key = cert.getPublicKey();
        cert.verify(key);

        System.out.println("OK");

Вроде сработало.
Offline miser  
#8 Оставлено : 18 июля 2018 г. 17:03:11(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 14.03.2011(UTC)
Сообщений: 153
Мужчина
Откуда: Санкт-Петербург

Сказал «Спасибо»: 1 раз
Поблагодарили: 7 раз в 5 постах
Я попробовал немного по другому пойти. http://www.bouncycastle.org/
Цитата:

Java Release 1.60 is now available for download.
Saturday 30th June 2018

Взял новую версию и случилось чудо. Сертификат проверился. Буду проверять дальше.
Предлагаю вам подумать о переходе, в дистрибутиве, на новую версию BouncyCastle.

Ваш код интересен в первую очередь для монопольного использования. Если понадобится использовать в двух ear модулях, или, не дай бог, в OSGi, могут возникнуть проблемы использования разных ClassLoader.

Еще раз, спасибо за оперативную помощь.

Отредактировано пользователем 18 июля 2018 г. 17:21:42(UTC)  | Причина: Не указана

Offline Евгений Афанасьев  
#9 Оставлено : 18 июля 2018 г. 18:25:45(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 715 раз в 675 постах
Спасибо, в будущем обновим версию bc, хотя jcp имеет косвенное отношение к bc (другая реализация криптографии, поэтому сообщение из первого поста не связано с jcp, используются алгоритмы не jcp, а bc, и среди них не хватало гост 2012. Или у вас смешанный проект с jcp и bc?).
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.