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

Уведомление

Icon
Error

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

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

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

Сказал(а) «Спасибо»: 2 раз
добрый день.
Стоит задача с помощью Java CSP подписывать файлы, например PDF. Подпись требуется открепленная, в формате CMS.
Делал по примерам из samples-sources.jar:

Код:

public void signPdf(File pdfFile) throws Exception {       

        KeyStore keyStore = KeyStore.getInstance("HDIMAGE", "JCSP");
        keyStore.load(null, null);

        PrivateKey privateKey = (PrivateKey) keyStore.getKey(KEY_CONT_ALIAS, PASSWORD);
        X509Certificate certificate = (X509Certificate) keyStore.getCertificate(KEY_CONT_ALIAS);
        Signature signature = Signature.getInstance(JCP.CRYPTOPRO_SIGN_2012_256_NAME, "JCSP");
        signature.initSign(privateKey);
        FileInputStream fData = new FileInputStream(new File("testdata/test.pdf"));
        int read;
        while ((read = fData.read()) != -1) {
            signature.update((byte)read);
        }
        fData.close();       

        byte[] cms = createCMSEx(null, signature.sign(), certificate, true,
                JCP.GOST_DIGEST_OID, JCP.GOST_EL_KEY_OID);        
        Array.writeFile("testdata/sign.dat", cms);

        //проверка подписи
        signature = Signature.getInstance(JCP.CRYPTOPRO_SIGN_2012_256_NAME);
        signature.initVerify(certificate.getPublicKey());
        readAndHash(signature, pdfFile.getAbsolutePath());

        verify(cms, certificate, signature);


    }

public static byte[] createCMSEx(byte[] buffer, byte[] sign,
                                     Certificate cert, boolean detached, String digestOid,
                                     String signOid) throws Exception {

        final ContentInfo all = new ContentInfo();
        all.contentType = new Asn1ObjectIdentifier(
                new OID("1.2.840.113549.1.7.2").value);

        final SignedData cms = new SignedData();
        all.content = cms;
        cms.version = new CMSVersion(1);

        // digest
        cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
        final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(
                new OID(digestOid).value);

        a.parameters = new Asn1Null();
        cms.digestAlgorithms.elements[0] = a;

        if (detached) {
            cms.encapContentInfo = new EncapsulatedContentInfo(
                    new Asn1ObjectIdentifier(
                            new OID("1.2.840.113549.1.7.1").value), null);
        } // if
        else {
            cms.encapContentInfo =
                    new EncapsulatedContentInfo(new Asn1ObjectIdentifier(
                            new OID("1.2.840.113549.1.7.1").value),
                            new Asn1OctetString(buffer));
        } // else

        // certificate
        cms.certificates = new CertificateSet(1);
        final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate certificate =
                new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
        final Asn1BerDecodeBuffer decodeBuffer =
                new Asn1BerDecodeBuffer(cert.getEncoded());
        certificate.decode(decodeBuffer);

        cms.certificates.elements = new CertificateChoices[1];
        cms.certificates.elements[0] = new CertificateChoices();
        cms.certificates.elements[0].set_certificate(certificate);

        // signer info
        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 = ((X509Certificate) cert)
                .getIssuerX500Principal().getEncoded();
        final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
        final Name name = new Name();
        name.decode(nameBuf);

        final CertificateSerialNumber num = new CertificateSerialNumber(
                ((X509Certificate) cert).getSerialNumber());
        cms.signerInfos.elements[0].sid.set_issuerAndSerialNumber(
                new IssuerAndSerialNumber(name, num));
        cms.signerInfos.elements[0].digestAlgorithm =
                new DigestAlgorithmIdentifier(new OID(digestOid).value);
        cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
        cms.signerInfos.elements[0].signatureAlgorithm =
                new SignatureAlgorithmIdentifier(new OID(signOid).value);
        cms.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null();
        cms.signerInfos.elements[0].signature = new SignatureValue(sign);

        // encode
        final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
        all.encode(asnBuf, true);
        return asnBuf.getMsgCopy();
    }


Примеры взял из класса DetachedSignatureFileExample, код метода verify() приводить не буду, так как это не принципиально.

Сделал тестовый сертификат в онлайн-сервисе КриптоПРО. Суть в том, что созданная подпись в формате cms при проверке на сайте гос.услуги, а так же в онлайн-сервисе проверки КриптоПРО считается недействительной. По методу verify() взятому из того же класса DetachedSignatureFileExample проверка проходит нормально.
Предполагаю, что проблемы связаны с передачей констант в метод createCMSex(), но на 100% не уверен. Во всяком случае, судя по дебаггеру все идет хорошо до вызова этого метода.
На всякий случай, ключ со следующими характеристиками:
*** Ключ обмена***
ГОСТ Р 34.10-2012 DH 256 бит
Неэкспортируемый

* Параметры подписи и обмена:
ГОСТ Р 34.10 256 бит, параметры обмена по умолчанию
* Параметры хэширования:
Функция хэширования ГОСТ Р 34.11-2012 (256)
* Параметры шифрования:
ГОСТ 28147-89, TC 26 параметры шифрования Z

Прошу помочь разобраться с данной проблемой, если потребуется - предоставлю дополнительные сведения
Offline Евгений Афанасьев  
#2 Оставлено : 13 июля 2021 г. 14:38:25(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Здравствуйте.
1) Попробуйте алгоритм подписи задать JCP.GOST_SIGN_2012_256_NAME;
2) приведите детали проверки и ошибки, которые возникают при проверке сторонним сервисом.
thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
vetal22331122 оставлено 13.07.2021(UTC)
Offline Санчир Момолдаев  
#3 Оставлено : 13 июля 2021 г. 14:40:18(UTC)
Санчир Момолдаев

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

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

Сказал(а) «Спасибо»: 88 раз
Поблагодарили: 223 раз в 211 постах
Добрый день
JCP.GOST_DIGEST_OID, JCP.GOST_EL_KEY_OID - это 2001 гост, а ключ и сертификат у вас скорее всего 2012
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Санчир Момолдаев за этот пост.
vetal22331122 оставлено 13.07.2021(UTC)
Offline vetal22331122  
#4 Оставлено : 13 июля 2021 г. 15:45:12(UTC)
vetal22331122

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

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

Сказал(а) «Спасибо»: 2 раз
Автор: Евгений Афанасьев Перейти к цитате
Здравствуйте.
1) Попробуйте алгоритм подписи задать JCP.GOST_SIGN_2012_256_NAME;
2) приведите детали проверки и ошибки, которые возникают при проверке сторонним сервисом.


Автор: Санчир Момолдаев Перейти к цитате
Добрый день
JCP.GOST_DIGEST_OID, JCP.GOST_EL_KEY_OID - это 2001 гост, а ключ и сертификат у вас скорее всего 2012


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