Я пытаюсь извлечь данные цифровой подписи из подписанного PDF-файла с помощью iTextPDF на Java. Мой код:

PdfReader reader = new PdfReader(is);
AcroFields af = reader.getAcroFields();
ArrayList<String> names = af.getSignatureNames();
if(names == null || names.isEmpty()) return null;
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(null, null);
    ArrayList<Map<QName, Serializable>> aspects = new ArrayList<Map<QName, Serializable>>();
    for (String name : names) {
        System.out.println("Signature name: " + name);
        System.out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
        System.out.println("Document revision: " + af.getRevision(name) + " of " + af.getTotalRevisions());

        PdfPKCS7 pk = af.verifySignature(name);
        X509Certificate certificate = pk.getSigningCertificate();

        Map<QName, Serializable> aspectSignatureProperties = new HashMap<QName, Serializable>(); 
        aspectSignatureProperties.put(SignModel.PROP_CERTIFICATE_PRINCIPAL, certificate.getSubjectX500Principal().toString());
        aspectSignatureProperties.put(SignModel.PROP_CERTIFICATE_SERIAL_NUMBER, certificate.getSerialNumber().toString());
        aspectSignatureProperties.put(SignModel.PROP_CERTIFICATE_NOT_AFTER, certificate.getNotAfter());
        aspectSignatureProperties.put(SignModel.PROP_CERTIFICATE_ISSUER, certificate.getIssuerX500Principal().toString());   
        aspects.add(aspectSignatureProperties);
    }

Однако в PdfPKCS7 pk = af.verifySignature(name); я получаю это исключение:

Caused by: java.lang.NoClassDefFoundError: org/bouncycastle/asn1/ASN1ObjectIdentifier
at com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2349)
at com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2302)
at es.keensoft.alfresco.behaviour.CustomBehaviour.getDigitalSignatures(CustomBehaviour.java:133)
at es.keensoft.alfresco.behaviour.CustomBehaviour.onCreateNode(CustomBehaviour.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.alfresco.repo.policy.JavaBehaviour$JavaMethodInvocationHandler.invoke(JavaBehaviour.java:174)
at com.sun.proxy.$Proxy54.onCreateNode(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.alfresco.repo.policy.TransactionBehaviourQueue.execute(TransactionBehaviourQueue.java:245)
... 41 more

Caused by: java.lang.ClassNotFoundException: org.bouncycastle.asn1.ASN1ObjectIdentifier at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1702) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547) ... 56 more

Я попытался включить зависимости BouncyCastle, но потом получил:

Информация о подписавшем не совпадает

Любые идеи? Благодарность

РЕДАКТИРОВАТЬ:

Я использую Maven со следующими зависимостями:

<dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.0</version>
    </dependency>

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.49</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpkix-jdk15on</artifactId>
        <version>1.49</version>
    </dependency>

И я получаю следующую ошибку:

java.lang.SecurityException: class "org.bouncycastle.asn1.ASN1ObjectIdentifier"'s signer information does not match signer information of other classes in the same package
1
The Macedon 26 Июн 2016 в 18:00
2
Какую версию BouncyCastle вы используете? Если вы используете Maven, запустите эту команду и добавьте результат в свой вопрос: mvn dependency:tree -Dverbose
 – 
Amedee Van Gasse
26 Июн 2016 в 20:03
Выполнено. Извините, я не понял этого раньше.
 – 
The Macedon
26 Июн 2016 в 20:19
Что-нибудь?
 – 
The Macedon
29 Июн 2016 в 12:14
Извини не знаю. Я добавил к вашему вопросу тег bouncycastle, потому что это ошибка BouncyCastle.
 – 
Amedee Van Gasse
1 Июл 2016 в 14:33
На самом деле это похоже на то, что у вас есть разные Jar-файлы, содержащие классы в пакете org.bouncycastle.asn1. Скорее всего несколько банок BouncyCastle для разных версий. В более общем плане ваша кодовая база или какая-либо другая библиотека, которая есть в вашем пути к классам, приносит с собой дополнительную копию некоторых классов BouncyCastle.
 – 
mkl
1 Июл 2016 в 16:00

1 ответ

Лучший ответ

Попробуйте использовать это:

  <dependencies>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.50</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpkix-jdk15on</artifactId>
        <version>1.50</version>
    </dependency>        
    <dependency>                    
        <groupId>com.itextpdf.tool</groupId>
        <artifactId>xmlworker</artifactId>
        <version>5.5.0</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.0</version>
    </dependency>
  </dependencies>

Зависимости явно не декларируются iText в Maven.

Как утверждают другие пользователи в ответах, 1.49 отлично работает с 5.5.0. Первые версии iText для MAVEN, в которых не было столь четкого управления зависимостями (об этом говорил даже Бруно Ловаги).

Проблема, похоже, в том, что существующие артефакты 1,45 мешают выполнению. В этом случае подойдет следующая комбинация библиотек.

  <dependencies>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.45</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpkix-jdk15on</artifactId>
        <version>1.45</version>
    </dependency>        
    <dependency>                    
        <groupId>com.itextpdf.tool</groupId>
        <artifactId>xmlworker</artifactId>
        <version>5.0.6</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.0.6</version>
    </dependency>
  </dependencies>
1
Angel Borroy 1 Июл 2016 в 17:43
Происходит то же самое: java.lang.SecurityException: class "org.bouncycastle.asn1.ASN1ObjectIdentifier"'s signer information does not match signer information of other classes in the same package. :(
 – 
The Macedon
29 Июн 2016 в 18:48
1
Это не сработает, BC 1.50 несовместим с iText 5.5.x. Вам действительно нужно 1,49.
 – 
Amedee Van Gasse
1 Июл 2016 в 14:29
1
Зависимости явно не объявляются iText в Maven. Это тоже неверно, если вы посмотрите на POM: github.com/itext/itextpdf/blob/5.5.0/itext/pom.xml
 – 
Amedee Van Gasse
1 Июл 2016 в 14:31
Похоже, он работает и с BC 1.49. Взгляните на github.com/angelborroy-ks/signature-position.
 – 
Angel Borroy
1 Июл 2016 в 17:36
Возможно, проблема в том, что вы развертываете среду, в которой уже есть эти библиотеки BC (bcmail-jdk15-1.45.jar, bcprov-jdk15-1.45.jar). В этом случае вам необходимо перейти на текстовую версию 5.0.6, чтобы использовать эту версию BC.
 – 
Angel Borroy
1 Июл 2016 в 17:41