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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline vas239  
#1 Оставлено : 8 октября 2015 г. 16:08:25(UTC)
vas239

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

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

Сказал(а) «Спасибо»: 7 раз
Здравствуйте!

JCP 1.0.54 - 2.0 использовать не могу.

Я подписываю на сервере документ по примерам так:

Код:
public static byte[] createHashCMSEx(final byte[] data, final boolean isExternalDigest,
                                         final PrivateKey[] keys, final Certificate[] certs, final String path,
                                         final boolean detached,
                                         final boolean addSignCertV2, final String digestOid, final String signOid,
                                         final String digestAlg,
                                         final String signAlg, final String providerName) throws Exception {
        //create hashCMS
        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;
        // Нельзя сделать подпись совмещенной, если нет данных, а есть только хеш с них.
        if (isExternalDigest && !detached) {
            throw new Exception("Signature is attached but external digest is available only (not data)");
        }
        if (detached) {
            cms.encapContentInfo = new EncapsulatedContentInfo(
                    new Asn1ObjectIdentifier(new OID(STR_CMS_OID_DATA).value), null);
        } else {
            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);
        }
        // Signature.getInstance
        final Signature signature = Signature.getInstance(signAlg, providerName);
        byte[] sign;
        // signer infos
        final int nsign = keys.length;
        cms.signerInfos = new SignerInfos(nsign);
        for (int i = 0; i < cms.signerInfos.elements.length; i++) {
            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();
            //signedAttributes
            final int kmax = addSignCertV2 ? 4 : 3;
            cms.signerInfos.elements[i].signedAttrs = new SignedAttributes(kmax);
            //-contentType
            int k = 0;
            cms.signerInfos.elements[i].signedAttrs.elements[k] =
                    new Attribute(new OID(STR_CMS_OID_CONT_TYP_ATTR).value, new Attribute_values(1));
            final Asn1Type conttype = new Asn1ObjectIdentifier(new OID(STR_CMS_OID_DATA).value);
            cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = conttype;
            //-Time
            k += 1;
            cms.signerInfos.elements[i].signedAttrs.elements[k] =
                    new Attribute(new OID(STR_CMS_OID_SIGN_TYM_ATTR).value, new Attribute_values(1));
            final Time time = new Time();
            final Asn1UTCTime utcTime = new Asn1UTCTime();
            //текущая дата с календаря
            utcTime.setTime(Calendar.getInstance());
            time.set_utcTime(utcTime);
            cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] =
                    time.getElement();
            //-message digest
            k += 1;
            cms.signerInfos.elements[i].signedAttrs.elements[k] =
                    new Attribute(new OID(STR_CMS_OID_DIGEST_ATTR).value, new Attribute_values(1));
            final byte[] messageDigestBlob;
            // Если вместо данных у нас хеш, то сразу его передаем, ничего не вычисляем.
            if (isExternalDigest) {
                messageDigestBlob = data;
            } else {
                if (detached) {
                    messageDigestBlob = digestm(data, digestAlg, providerName);
                } else {
                    messageDigestBlob = digestm(cms.encapContentInfo.eContent.value, digestAlg, providerName);
                }
            }
            final Asn1Type messageDigest = new Asn1OctetString(messageDigestBlob);
            cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = messageDigest;
            // Добавление signingCertificateV2 в подписанные аттрибуты, чтобы подпись стала похожа на CAdES-BES.
            if (addSignCertV2) {
                // Собственно, аттрибут с OID'ом id_aa_signingCertificateV2.
                k += 1;
                cms.signerInfos.elements[i].signedAttrs.elements[k] = new Attribute(
                        new OID(ALL_PKIX1Explicit88Values.id_aa_signingCertificateV2).value, new Attribute_values(1));
                // Идентификатор алгоритма хеширования, который использовался для
                // хеширования контекста сертификата ключа подписи.
                final DigestAlgorithmIdentifier digestAlgorithmIdentifier =
                        new DigestAlgorithmIdentifier(new OID(digestOid).value);
                // Хеш сертификата ключа подписи.
                final CertHash certHash = new CertHash(digestm(certs[i].getEncoded(), digestAlg, providerName));
                // Issuer name из сертификата ключа подписи.
                GeneralName generalName = new GeneralName();
                generalName.set_directoryName(name);
                GeneralNames generalNames = new GeneralNames();
                generalNames.elements = new GeneralName[1];
                generalNames.elements[0] = generalName;
                // Комбинируем издателя и серийный номер.
                IssuerSerial issuerSerial = new IssuerSerial(generalNames, num);
                ESSCertIDv2 essCertIDv2 = new ESSCertIDv2(digestAlgorithmIdentifier, certHash, issuerSerial);
                _SeqOfESSCertIDv2 essCertIDv2s = new _SeqOfESSCertIDv2(1);
                essCertIDv2s.elements = new ESSCertIDv2[1];
                essCertIDv2s.elements[0] = essCertIDv2;
                // Добавляем сам аттрибут.
                SigningCertificateV2 signingCertificateV2 = new SigningCertificateV2(essCertIDv2s);
                cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = signingCertificateV2;
            }
            //signature
            Asn1BerEncodeBuffer encBufSignedAttr = new Asn1BerEncodeBuffer();
            cms.signerInfos.elements[i].signedAttrs.encode(encBufSignedAttr);
            final byte[] hsign = encBufSignedAttr.getMsgCopy();
            signature.initSign(keys[i]);
            signature.update(hsign);
            sign = signature.sign();
            cms.signerInfos.elements[i].signature = new SignatureValue(sign);
        }
        // encode
        final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
        all.encode(asnBuf, true);
        final byte[] msgCopy = asnBuf.getMsgCopy();
        if (path != null) {
            Array.writeFile(path, msgCopy);
        }
        return msgCopy;
    }



А дальше я усовершенствую эту подпись до CAdES_X_Long_Type_1:

Код:
/**
     * Усовершенствование CAdES-BES подписи до CAdES-X Long Type 1.
     *
     * @param signature Подпись для усовершенствования.
     * @param file      подписываемый файл.
     * @param chain     цепочка сертификатов.
     * @param tsaAddress     адрес службы штампов.
     * @return усовершенствованная подпись
     * @throws CAdESException /
     * @throws IOException /
     */
    public static byte[] enhanceSignature(final byte[] signature, final byte[] file,
                                          final Collection<X509Certificate> chain, final String tsaAddress) throws CAdESException, IOException {
        CAdESSignature cadesSignature = new CAdESSignature(signature, file, null);
        LOG.debug("Start verify signature with chain size {}, {}", chain.size(), chain);
        cadesSignature.verify(chain, null);

        // Список всех подписантов в исходной подписи.
        final Collection<SignerInformation> srcSignerInfos = new ArrayList<SignerInformation>();

        for (CAdESSigner signer : cadesSignature.getCAdESSignerInfos()) {
            srcSignerInfos.add(signer.getSignerInfo());
        }
        // 2. Усовершенствование подписи.

        // Получаем только первую CAdES-BES подпись, усовершенствуем ее.
        // Остальных не трогаем.
        final CMSSignedData srcSignedData = cadesSignature.getSignedData();
        final CAdESSigner srcSigner = cadesSignature.getCAdESSignerInfo(0);

        // Исключаем ее из исходного списка, т.к. ее место займет усовершенствованная
        // подпись.
        srcSignerInfos.remove(srcSigner.getSignerInfo());

        // Усовершенствуем CAdES-BES до CAdES-X Long Type 1.
        srcSigner.enhance(JCP.PROVIDER_NAME, JCP.GOST_DIGEST_OID, chain,
                tsaAddress, CAdESType.CAdES_X_Long_Type_1);

        // Подписант усовершенствованной подписи.
        final SignerInformation enhSigner = srcSigner.getSignerInfo();

        // Добавляем его в исходный список подписантов.
        srcSignerInfos.add(enhSigner);

        // Список подписантов.
        final SignerInformationStore dstSignerInfoStore = new SignerInformationStore(srcSignerInfos);

        // Обновляем исходную подпись c ее начальным списком подписантов на тот же,
        // но с первым подписантом с усовершенствованной подписью.
        final CMSSignedData dstSignedData =
                CMSSignedData.replaceSigners(srcSignedData, dstSignerInfoStore);

        // 3. Проверка усовершенствованной подписи.

        // Проверяем подпись.
        cadesSignature = new CAdESSignature(dstSignedData.getEncoded(), file, null);
        cadesSignature.verify(chain, null);

        printSignatureInfo(cadesSignature);

        return cadesSignature.getSignedData().getEncoded();
    }



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