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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Дмитрий1902  
#1 Оставлено : 27 марта 2016 г. 17:42:12(UTC)
Дмитрий1902

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

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

Поблагодарили: 2 раз в 1 постах
Добрый день!
Подскажите как добавить несколько подписей к одному pdf документу?
Первую подпись к pdf документу добавляю следующим образом

Код:

 public static void main(String args[]) throws Exception {
        String source = "Y:\\Documents\\NetBeansProjects\\esign\\sample.pdf";
        String signed_file = "Y:\\Documents\\NetBeansProjects\\esign\\signed_file.pdf";
        PdfReader reader = new PdfReader(source);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfStamper stamper = PdfStamper.createSignature(reader, new FileOutputStream(signed_file), '\0');
        PdfSignatureAppearance sap = stamper.getSignatureAppearance();
        sap.setReason("Test");
        sap.setLocation("On a server!");
        sap.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
        Certificate cert = getCertificate();
        Certificate[] chain = {cert};
        sap.setCertificate(chain[0]);
        PdfSignature dic = new PdfSignature(
                PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
        dic.setReason(sap.getReason());
        dic.setLocation(sap.getLocation());
        dic.setContact(sap.getContact());
        dic.setDate(new PdfDate(sap.getSignDate()));
        sap.setCryptoDictionary(dic);
        HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
        Integer csize = 8192;
        exc.put(PdfName.CONTENTS, new Integer(csize * 2 + 2));
        sap.preClose(exc);
        KeyStore ks = KeyStore.getInstance(JCP.HD_STORE_NAME);
        String alias = "61a241ac4-ac58-22b4-2ba4-921b982a534";
        ks.load(null, null);
        PrivateKey pk = (PrivateKey) ks.getKey(alias, "12345678".toCharArray());
        byte[] data = CMSSign(IOUtils.toByteArray(sap.getRangeStream()), pk, cert, true);
        System.out.println(new String(data));        
        byte[] outc = new byte[csize];
        PdfDictionary dic2 = new PdfDictionary();
        System.arraycopy(data, 0, outc, 0, data.length);
        dic2.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));
        sap.close(dic2);

    }
    
    public static Certificate getCertificate() throws Exception {
        String cert_path = "Y:\\Documents\\NetBeansProjects\\esign\\publicCert.crt";
        FileInputStream is = new FileInputStream(cert_path);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        Certificate cert = cf.generateCertificate(is);
        return cert;
    }
    
    public static byte[] CMSSign(byte[] data, PrivateKey key, Certificate cert,
            boolean detached)
            throws Exception {
        // sign
        //Возвращает объект Signature, который реализует указанный алгоритм подписи.
        final Signature signature =
                Signature.getInstance(JCP.GOST_EL_SIGN_NAME);
        //Инициализировать объект для подписания.
        signature.initSign(key);
        //Обновление данных, которые должны быть подписаны.
        signature.update(data);
        //Возвращает байты сигнатуры
        final byte[] sign = signature.sign();
        //создаем cms подпись      
        return createCMS(data, sign, cert, detached);
    }
    
    public static byte[] createCMS(byte[] buffer, byte[] sign, Certificate cert,
            boolean detached)
            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(JCP.GOST_DIGEST_OID).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);
        } else {
            cms.encapContentInfo =
                    new EncapsulatedContentInfo(new Asn1ObjectIdentifier(
                    new OID("1.2.840.113549.1.7.1").value),
                    new Asn1OctetString(buffer));
        }
        // 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(JCP.GOST_DIGEST_OID).value);
        cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
        cms.signerInfos.elements[0].signatureAlgorithm =
                new SignatureAlgorithmIdentifier(new OID(JCP.GOST_EL_KEY_OID).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();
    }


Как мне добавить еще одну подпись, другого человека, к подписанному документу? Те чтобы документ был подписан двумя разными ключами.
Примеров в JCP/sample по данной проблеме не нашел(( Если есть образец кода то будет супер или направьте куда рыть)
Спасибо

Отредактировано пользователем 27 марта 2016 г. 17:43:07(UTC)  | Причина: Не указана

Offline Дмитрий1902  
#2 Оставлено : 18 мая 2016 г. 11:22:43(UTC)
Дмитрий1902

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

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

Поблагодарили: 2 раз в 1 постах
В общем все сделал

генерим hash 94
Код:

 private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        try {
            PdfReader reader = new PdfReader(this.source);
            FileOutputStream os = new FileOutputStream(this.signed_file);
            PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
            PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
            appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "first");
            ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
            MakeSignature.signExternalContainer(appearance, external, 8192);
            byte[] data = IOUtils.toByteArray(appearance.getRangeStream());
            MessageDigest md = MessageDigest.getInstance(JCP.GOST_DIGEST_NAME);
            md.update(data);
            byte[] fileDigest = md.digest();
            this.TBHash94.setText(Hex.encodeHexString(fileDigest));

        } catch(Exception e) {
            System.out.println(e);
        }
    }        


Подписываем документ подписью (хэш подписал в браузере)
Код:

private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        try {
            PdfReader reader = new PdfReader(this.signed_file);
            FileOutputStream os = new FileOutputStream(this.signed_file2);
            String sign64 = this.TBSign.getText();
            Decoder decoder = new Decoder();
            byte[] sign = decoder.decodeBuffer(sign64);
            ExternalSignatureContainer external = new MyExternalSignatureContainer(sign);
            MakeSignature.signDeferred(reader, "first", os, external);
         } catch(Exception e) {
            System.out.println(e);
        }
    }                


ну и чтобы добавить еще подписи в подписанный документ меняем строчки

PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
....
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "first");
...
MakeSignature.signDeferred(reader, "first", os, external);

на

PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', null, true);
...
appearance.setVisibleSignature(new Rectangle(136, 748, 244, 780), 1, "second");
...
MakeSignature.signDeferred(reader, "second", os, external);

вот пажалуй и все))

Отредактировано пользователем 18 мая 2016 г. 12:24:44(UTC)  | Причина: Не указана

thanks 2 пользователей поблагодарили Дмитрий1902 за этот пост.
BufferOverflow оставлено 24.10.2016(UTC), Vadim_Pil оставлено 28.10.2019(UTC)
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.