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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Андрей Алексеевич  
#1 Оставлено : 6 сентября 2024 г. 19:32:02(UTC)
Андрей Алексеевич

Статус: Новичок

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

Сказал(а) «Спасибо»: 1 раз
Задача проверить только подпись, без цепочки сертификатов. Подписывать я не умею пока, поэтому взял уже подписанный документ с открепленной подписью (sig). Проверил его на госуслугах, валидный.
[img=https://postimg.cc/678h0Cz9]проверка на госуслугах[/img]
Установил КриптоПро CSP 5.0 R3 KC2 и пытаюсь его проверить. Сначала сделал с CadeS, работает, но обращается в интернет для СОС. А мне сертификаты пока не нужны, только подпись проверить по открытому ключу. Написал вот такой код:
Код:

public static void Start() throws Exception {
        System.setProperty("file.encoding", "UTF-8");
        Security.addProvider(new JCSP());
        Security.addProvider(new CryptoProvider());
        log.info("Выполнена настройка");
        final byte[] data = Files.readAllBytes(
            Paths.get("PFR_101000_SV-360_20240815_ec03f39b-e2f3-4a1b-86f1-fe8c298333d3_06855466306.pdf"));
        final byte[] signature = Files.readAllBytes(
            Paths.get("PFR_101000_SV-360_20240815_ec03f39b-e2f3-4a1b-86f1-fe8c298333d3_06855466306.pdf.sig"));
        log.info("Прочитал файл и подпись");
        CAdESSignature cAdESSignature = new CAdESSignature(signature, data, CAdESType.CAdES_BES);
        // Извлечь сертификаты, их может быть несколько
        CollectionStore userCerts = cAdESSignature.getCertificateStore();

        for (Object o : userCerts) {
            // Извлечение сертификата
            X509CertificateHolder certificateHolder = (X509CertificateHolder) o;
            X509Certificate certificate = new JcaX509CertificateConverter().getCertificate(certificateHolder);
            certificatePrintInfo(certificate);
            // Сохраняю сертификат, для отладки
            Files.write(Path.of("debug.cer"), certificate.getEncoded());
            // Проверка подписи только по сертификату, без цепочки
            final Signature sig = Signature.getInstance(JCP.GOST_SIGN_2012_256_NAME, JCSP.PROVIDER_NAME);
            sig.initVerify(certificate.getPublicKey());
            sig.update(data);
            byte[] byteSignature = cAdESSignature.getCAdESSignerInfos()[0].getSignerInfo().getSignature();
            log.info("Подпись: {} (длина {})", Hex.toHexString(byteSignature), byteSignature.length);
            boolean checkResult = sig.verify(byteSignature);
            log.info("Результат проверки: {} ", checkResult ? "Валидна" : "Невалидна");
        }
    }


Чтобы я не делал, всегда подпись не валидна. Может кто-то уже сталкивался с такой задачей? Более конкретные вопросы:
1. Как правильно указать название алгоритмя для Signature.getInstance, где его можно посмотреть ( PFR_101000_SV-360_20240815_ec03f39b-e2f3-4a1b-86f1-fe8c298333d3_06855466306.pdf.sig (4kb) загружен 2 раз(а). приложил). Документ подписывал не я, поэтому не знаю какой алгоритм.Но при проверке на госуслугах его как-то сами определили.
2. Правильно ли извлекаю открытый ключ, смущает что в нем "3066301f06082a85030701010101301306072a85030202240006082a850307010102020343000440c6293f69e52a7e543c02b7e082fdff5d0b072052a8a1869cba436a266c8e0e62e294d9e1415c8314155efd723df990072634e452bca233254cb324917076cd6c", а при просмотре сертификата
Цитата:

Открытый ключ: 04 40 C6 29 3F 69 E5 2A 7E 54 3C 02 B7 E0 82 FD FF 5D 0B 07 20 52 A8 A1 86 9C BA 43 6A 26 6C 8E 0E 62 E2 94 D9 E1 41 5C 83 14 15 5E FD 72 3D F9 90 07 26 34 E4 52 BC A2 33 25 4C B3 24 91 70 76 CD 6C

т.е. в извлеченном мной еще есть много стартовых байтов.

Результат работы кода
Цитата:

2024-09-06 19:00:06 INFO Выполнена настройка
2024-09-06 19:00:06 INFO Прочитал файл и подпись
2024-09-06 19:00:06 INFO Формат публичного ключа: X.509
2024-09-06 19:00:06 INFO Публичный ключ: 3066301f06082a85030701010101301306072a85030202240006082a850307010102020343000440c6293f69e52a7e543c02b7e082fdff5d0b072052a8a1869cba436a266c8e0e62e294d9e1415c8314155efd723df990072634e452bca233254cb324917076cd6c
2024-09-06 19:00:06 INFO Действует с 2023-10-30T13:59:00.000+0300 по 2025-01-22T13:59:00.000+0300
сент. 06, 2024 7:00:06 PM ru.CryptoPro.JCSP.Starter <init>
INFO: Loading Java CSP 5.0.45549-A, Crypto-Pro CSP 5.0.13000
сент. 06, 2024 7:00:06 PM ru.CryptoPro.JCSP.Starter <init>
INFO: Java CSP has been loaded.
2024-09-06 19:00:06 INFO Подпись: edce2fdd94d23c848a018c1b153c5da2adf1c9b47ca7e3c2bc967c1f3c05e23eb6afe165c09da34e8355e662498bd179e27d38819118b5f78d85f20d86be9e66 (длина 64)
2024-09-06 19:00:06 INFO Результат проверки: Невалидна

Process finished with exit code 0


Offline Санчир Момолдаев  
#2 Оставлено : 6 сентября 2024 г. 23:51:16(UTC)
Санчир Момолдаев

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

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

Сказал(а) «Спасибо»: 93 раз
Поблагодарили: 256 раз в 241 постах
Класс Signature предназначен для сырой подписи.
посмотрите пример формирования и проверки CMS* в samples-sources.jar
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Санчир Момолдаев за этот пост.
Андрей Алексеевич оставлено 07.09.2024(UTC)
Offline Андрей Алексеевич  
#3 Оставлено : 7 сентября 2024 г. 13:29:06(UTC)
Андрей Алексеевич

Статус: Новичок

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

Сказал(а) «Спасибо»: 1 раз
Автор: Санчир Момолдаев Перейти к цитате
Класс Signature предназначен для сырой подписи.
посмотрите пример формирования и проверки CMS* в samples-sources.jar

Посмотрел. Так конечно очень много кода и вопросов к нему, но пока использовал его целиком, чтобы начать. К своему коду добавил три строки (последние), чтобы использовать уже извлеченные раннее подпись, сертификаты и подписанные данные. И оно заработало. Спасибо.
Код:

  boolean checkResult = sig.verify(byteSignature);
  log.info("Результат проверки: {} ", checkResult ? "Валидна" : "Невалидна");
  Certificate[] certificates = new Certificate[1];
  certificates[0] =certificate;
  CMSVerify.CMSVerify(signature, certificates, data);


Offline Санчир Момолдаев  
#4 Оставлено : 7 сентября 2024 г. 13:45:03(UTC)
Санчир Момолдаев

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

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

Сказал(а) «Спасибо»: 93 раз
Поблагодарили: 256 раз в 241 постах
хорошо.
если на пальцах cades-bes проверяется так.
берутся подписанные атрибуты и без сортировки подаются на хэширование. именно этот хэш должен проверяться с Signature Value.
иногда атрибуты нужно сортировать, но это частный случай. обычно все передают как есть.

хэш самого подписанного файла будет в атрибуте Message Digest. значение оттуда сравниваете с получившимся хэшом от данных.
Техническую поддержку оказываем тут
Наша база знаний
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.