2017-06-23 12 views
1

私はiText5からiText7へコードを移行していますが、現在別の署名が入っているPDFに1つの署名を追加するのに苦労しています。 これらの署名は国民IDカード(市民カード)で行われます。複数の署名付きiText7 PDF

私はPdfStamperを使用しますが、それはiText7から欠落していますiText5で

...

これは私がこれまで持っているものです。

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)は、スマートカードと対話するために使用されるライブラリです。

初めてドキュメントに署名するときは正常に動作します。ドキュメントに再度署名すると、最初の署名が無効になり、最後の署名のみが有効になります。

PDF:

Two Signatures

答えて

2

署名コードが追加モードでPDFを開けないので、二度目に署名するときにコンテンツが変更され、最初の署名を破ります。追加モードでサインインして

、コンストラクタに単に次の行を変更

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

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

に第3引数は、署名者が追加モードで使用されているか否かを判定する。

+1

基本的な間違い...それは今働いています。ありがとう –

関連する問題