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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline coldplay  
#1 Оставлено : 7 июня 2016 г. 14:25:50(UTC)
coldplay

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

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

Сказал(а) «Спасибо»: 18 раз
Поблагодарили: 2 раз в 2 постах
Здравствуйте. Поскольку эта тема зашла в тупик
https://www.cryptopro.ru...aspx?g=posts&t=10341
то вместо примеров cades sign, использую примеры из cms. Столкнулся с проблемой верификации полученной подписи.

Методы подписи\проверки подписи :

Код:

   private static String digestOid = JCP.GOST_DIGEST_2012_512_OID;
    private static String signOid = JCP.GOST_PARAMS_SIG_2012_512_KEY_OID;
    private static java.lang.String signAlgorithm = JCP.GOST_SIGN_2012_512_NAME;
    private static String STR_CMS_OID_ENVELOPED = "1.2.840.113549.1.7.3";
    private static String STR_CMS_OID_DATA = "1.2.840.113549.1.7.1";
    private static String STR_CMS_OID_SIGNED = "1.2.840.113549.1.7.2";

......
 public byte[] sign(byte[] data, PrivateKey[] keys, Certificate[] certs) throws Exception {
        //create CMS
        final ContentInfo all = new ContentInfo();
        all.contentType = new Asn1ObjectIdentifier(
                new OID(STR_CMS_OID_SIGNED).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;


        cms.encapContentInfo =
                new EncapsulatedContentInfo(new Asn1ObjectIdentifier(
                        new OID(STR_CMS_OID_DATA).value),
                        new Asn1OctetString(data));

        // certificates
        final int nCerts = certs.length;
        cms.certificates = new CertificateSet(nCerts);
        cms.certificates.elements = new CertificateChoices[nCerts];

        for (int i = 0; i < cms.certificates.elements.length; i++) {

            final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate certificate =
                    new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
            final Asn1BerDecodeBuffer decodeBuffer =
                    new Asn1BerDecodeBuffer(certs[i].getEncoded());
            certificate.decode(decodeBuffer);

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

        } // for

        // Signature.getInstance
        final Signature signature = Signature.getInstance(signAlgorithm, "JCP");
        byte[] sign;

        // signer infos
        final int nSign = keys.length;
        cms.signerInfos = new SignerInfos(nSign);
        for (int i = 0; i < cms.signerInfos.elements.length; i++) {

            signature.initSign(keys[i]);
            signature.update(data);
            sign = signature.sign();

            cms.signerInfos.elements[i] = new SignerInfo();
            cms.signerInfos.elements[i].version = new CMSVersion(1);
            cms.signerInfos.elements[i].sid = new SignerIdentifier();

            final byte[] encodedName = ((X509Certificate) certs[i])
                    .getIssuerX500Principal().getEncoded();
            final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
            final Name name = new Name();
            name.decode(nameBuf);

            final CertificateSerialNumber num = new CertificateSerialNumber(
                    ((X509Certificate) certs[i]).getSerialNumber());
            cms.signerInfos.elements[i].sid.set_issuerAndSerialNumber(
                    new IssuerAndSerialNumber(name, num));
            cms.signerInfos.elements[i].digestAlgorithm =
                    new DigestAlgorithmIdentifier(new OID(digestOid).value);
            cms.signerInfos.elements[i].digestAlgorithm.parameters = new Asn1Null();
            cms.signerInfos.elements[i].signatureAlgorithm =
                    new SignatureAlgorithmIdentifier(new OID(signOid).value);
            cms.signerInfos.elements[i].signatureAlgorithm.parameters =
                    new Asn1Null();
            cms.signerInfos.elements[i].signature = new SignatureValue(sign);
        }
        // encode
        final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
        all.encode(asnBuf, true);
        return asnBuf.getMsgCopy();
    }


    private static void verify(byte[] sign, Certificate cert) throws Exception {
        Signature signature = Signature.getInstance(signAlgorithm, "JCP");

        Asn1BerDecodeBuffer asn1BerDecodeBuffer = new Asn1BerDecodeBuffer(sign);
        ContentInfo contentInfo = new ContentInfo();
        contentInfo.decode(asn1BerDecodeBuffer);
        SignedData content = (SignedData) contentInfo.content;
        byte[] signedData = content.encapContentInfo.eContent.value;

        signature.initVerify(cert.getPublicKey());
        signature.update(signedData);
        boolean verified = true;
        for (SignerInfo signerInfo : content.signerInfos.elements) {
            if (!signature.verify(signerInfo.signature.value)) {
                verified = false;
            }
        }
        if (!verified) {
            throw new RuntimeException("Failed to verify signed data!");
        }
    }



При проверке получаю исключение

Код:

java.security.SignatureException: Invalid length of signature
	at ru.CryptoPro.JCP.Sign.c.engineVerify(Unknown Source)
	at ru.CryptoPro.JCP.Sign.c.engineVerify(Unknown Source)
	at java.security.Signature.verify(Signature.java:627)
	at ru.test.testTest.verify(Test.java:119)

Offline Евгений Афанасьев  
#2 Оставлено : 7 июня 2016 г. 14:46:11(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 714 раз в 674 постах
Здравствуйте.
Проверьте длину signerInfo.signature.value, вероятно, она отличается от 64 байт. Кроме того, если не ошибаюсь, в CMSVerify (пакет CMS в samples-sources.jar) проверка организована по-другому.

Отредактировано пользователем 7 июня 2016 г. 15:42:26(UTC)  | Причина: Не указана

Offline coldplay  
#3 Оставлено : 7 июня 2016 г. 15:04:15(UTC)
coldplay

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

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

Сказал(а) «Спасибо»: 18 раз
Поблагодарили: 2 раз в 2 постах
В отладке проверил signerInfo.signature.value.length=64. В сэмплах проверка подписи

Код:

    // Проверяем подпись.
    Signature signature = Signature.getInstance(signAlg, providerName);
    signature.initVerify(cert);
    signature.update(data);

    boolean verified = signature.verify(sign);
Offline Евгений Афанасьев  
#4 Оставлено : 7 июня 2016 г. 15:45:35(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 714 раз в 674 постах
Автор: coldplay Перейти к цитате
signAlgorithm = JCP.GOST_SIGN_2012_512_NAME

Тогда должна быть 128 байт.

thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
coldplay оставлено 07.06.2016(UTC)
Offline coldplay  
#5 Оставлено : 7 июня 2016 г. 16:42:30(UTC)
coldplay

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

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

Сказал(а) «Спасибо»: 18 раз
Поблагодарили: 2 раз в 2 постах
Спасибо! Поменял при верификации алгоритм на GOST3411_2012_256withGOST3410_2012_256 верификация не разваливалась , но возвращала false. Соответсвенно поменяв алгоритм в подписи на такой же , получил true и тест прошел. А почему при
Signature signature = Signature.getInstance(JCP.GOST_SIGN_2012_512_NAME, "JCP");
я получал 64 байт сигны ?
Из-за инициализации приватным ключем, где были указаны какие то другие данные ?
signature.initSign(keys[i])
Offline Евгений Афанасьев  
#6 Оставлено : 7 июня 2016 г. 17:05:03(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 714 раз в 674 постах
Автор: coldplay Перейти к цитате
Спасибо! Поменял при верификации алгоритм на GOST3411_2012_256withGOST3410_2012_256 верификация не разваливалась , но возвращала false. Соответсвенно поменяв алгоритм в подписи на такой же , получил true и тест прошел. А почему при
Signature signature = Signature.getInstance(JCP.GOST_SIGN_2012_512_NAME, "JCP");
я получал 64 байт сигны ?
Из-за инициализации приватным ключем, где были указаны какие то другие данные ?
signature.initSign(keys[i])

А какой был ключ? ГОСТ 2001 или 2012 (256) или же 2012 (512)?

Offline coldplay  
#7 Оставлено : 14 июня 2016 г. 10:11:48(UTC)
coldplay

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

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

Сказал(а) «Спасибо»: 18 раз
Поблагодарили: 2 раз в 2 постах
Извиняюсь за задержку в ответе. Не стал ломать голову в соответсвии ключей. Просто все данные необходимые для подписи/проверки подписи беру из сертификата, а не хардкодом. Проблем больше не возникало.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.