2017-06-23 6 views
1

Ich migriere Code von iText5 zu iText7 und derzeit kämpfe ich mit dem Anhängen einer Unterschrift an ein PDF, das bereits eine andere Unterschrift enthält. Diese Unterschriften werden mit unserem Personalausweis (Bürgerkarte) gemacht.iText7 PDF mit mehreren Unterschriften

In iText5 verwendet i PdfStamper aber es ist von iText7 fehlt ...

Dies ist, was ich bisher:

package cartaocidadao; 

import java.io.FileOutputStream; 
import java.security.KeyStore; 
import java.security.PrivateKey; 
import java.security.Security; 
import java.security.cert.Certificate; 
import javax.swing.JOptionPane; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
import org.poreid.config.POReIDConfig; 
import org.poreid.crypto.POReIDProvider; 
import com.itextpdf.signatures.OcspClientBouncyCastle; 
import com.itextpdf.signatures.TSAClientBouncyCastle; 
import java.io.IOException; 
import java.util.Collection; 

import com.itextpdf.kernel.geom.Rectangle; 
import com.itextpdf.kernel.pdf.PdfReader; 
import com.itextpdf.signatures.BouncyCastleDigest; 
import com.itextpdf.signatures.ICrlClient; 
import com.itextpdf.signatures.DigestAlgorithms; 
import com.itextpdf.signatures.IExternalDigest; 
import com.itextpdf.signatures.IExternalSignature; 
import com.itextpdf.signatures.IOcspClient; 
import com.itextpdf.signatures.PdfSignatureAppearance; 
import com.itextpdf.signatures.PdfSigner; 
import com.itextpdf.signatures.PrivateKeySignature; 
import com.itextpdf.signatures.ITSAClient; 
import com.itextpdf.signatures.OCSPVerifier; 
import java.security.GeneralSecurityException; 
import static javax.swing.JOptionPane.ERROR_MESSAGE; 

/** 
* 
* @author i.lourenco 
*/ 
public class Signature { 

    /** 
    * Signs the PDF with the Citizen Card Certificate 
    * @param src Source file 
    * @param dest Destination file 
    * @return TRUE if the PDF was signed successfully 
    */ 
    protected static boolean signPDF(String src, String dest) { 

     try { 

      Security.addProvider(new POReIDProvider()); 

      BouncyCastleProvider provider = new BouncyCastleProvider(); 
      Security.addProvider(provider); 

      KeyStore ks = KeyStore.getInstance(POReIDConfig.POREID); 
      ks.load(null); 

      PrivateKey pk = (PrivateKey) ks.getKey(POReIDConfig.ASSINATURA, null); 

      Certificate[] chain = ks.getCertificateChain(POReIDConfig.ASSINATURA); 

      OCSPVerifier ocspVerifier = new OCSPVerifier(null, null); 

      IOcspClient ocspClient = new OcspClientBouncyCastle(ocspVerifier); 

      ITSAClient tsaClient = new TSAClientBouncyCastle("http://ts.cartaodecidadao.pt/tsa/server", "", ""); 

      sign(src, dest, chain, pk, DigestAlgorithms.SHA256, POReIDConfig.POREID, PdfSigner.CryptoStandard.CMS, "", "", null, ocspClient, tsaClient, 0); 
     } catch (Exception e) { 
      JOptionPane.showMessageDialog(null, e.getMessage(), "Erro", ERROR_MESSAGE); 
     } 

     return true; 
    } 

    /** 
    * Applies the certificate, timestamp and revocation list to a PDF 
    * @param src Original PDF document 
    * @param dest Signed PDF document 
    * @param chain List of certificates 
    * @param pk Private key 
    * @param digestAlgorithm Encryption algorithm 
    * @param provider Citizen Card provider 
    * @param subfilter CMS 
    * @param reason Reason for signature 
    * @param location Location 
    * @param crlList Revocation list 
    * @param ocspClient Online Certification Status 
    * @param tsaClient Timestamp server 
    * @param estimatedSize 
    * @throws IOException 
    * @throws GeneralSecurityException 
    */ 
    private static void sign(String src, String dest, Certificate[] chain, PrivateKey pk, String digestAlgorithm, 
      String provider, PdfSigner.CryptoStandard subfilter, String reason, String location, Collection<ICrlClient> crlList, 
      IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize) throws IOException, GeneralSecurityException { 

     PdfReader reader = new PdfReader(src); 

     PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), false); 

     PdfSignatureAppearance appearance = signer.getSignatureAppearance() 
       .setReason(reason) 
       .setLocation(location) 
       .setReuseAppearance(false); 
     Rectangle rect = new Rectangle(36, 648, 200, 100); 
     appearance.setPageRect(rect).setPageNumber(1); 

     signer.getNewSigFieldName(); 

     IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, provider); 
     IExternalDigest digest = new BouncyCastleDigest(); 

     signer.signDetached(digest, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter); 
    } 


} 

POReID (https://github.com/poreid/poreid) ist die Bibliothek verwendet, mit der Smartcard zu interagieren .

Wenn Sie das Dokument zum ersten Mal signieren, funktioniert es einwandfrei. Wenn Sie das Dokument erneut signieren, wird die erste Signatur ungültig, und nur die letzte ist gültig.

PDF:

Two Signatures

Antwort

2

Ihr Signaturcode wird die PDF in Zufügen-Modus nicht öffnen und somit den Inhalt ändern, wenn das zweite Mal der Unterzeichnung, die erste Signatur zu brechen.

Um in Anfügemodus unterzeichnen, einfach die folgende Zeile ändern

PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), false); 

zu

PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), true); 

Das dritte Argument im Konstruktor fest, ob der Unterzeichner im Append-Modus verwendet wird.

+1

Grundfehler ... Es funktioniert jetzt. Vielen Dank –

Verwandte Themen