2014-03-04 57 views
0

我需要知道如何用Java做的簽署PDF文檔幾次,恕不另行簽名仍然無效,這就是我的代碼:多次登錄PDF

CallbackHandler cmdLineHdlr = new DialogCallbackHandler(); 
    Callback[] callbacks = new Callback[]{new PasswordCallback("Contraseña: ", false)}; 
    cmdLineHdlr.handle(callbacks); 
    String password = new String(((PasswordCallback) callbacks[0]).getPassword()); 
    KeyStore ks = null; 
    try { 
     ks = KeyStore.getInstance("PKCS11"); 
     ks.load(null, password.toCharArray()); 
    } catch (Exception e) { 
     JOptionPane.showMessageDialog(null, "Digite una contraseña correcta", "Error", JOptionPane.ERROR_MESSAGE); 
     return "InvalidPass"; 
    } 
    Enumeration aliasesEnum = ks.aliases(); 
    PrivateKey key = null; 
    X509Certificate cert; 
    String aliass = null; 
    while (aliasesEnum.hasMoreElements()) { 
     aliass = (String) aliasesEnum.nextElement(); 
     cert = (X509Certificate) ks.getCertificate(aliass); 
     if (cert.getSubjectDN().getName().indexOf("(FIRMA)") > 0) { 
      key = (PrivateKey) ks.getKey(aliass, null); 
      break; 
     } 
    } 

    //Se carga el PDF original Ahora desde la web! 
    URL sisdoc = new URL(host + servletIN + fullpar); 
    //Se conecta al servlet que recibe el documento 
    URLConnection yc = sisdoc.openConnection(); 
    //Se carga el pdf 
    PdfReader pdf = new PdfReader(yc.getInputStream()); 

    URL sisdocRet = new URL(host + servletOUT + fullpar); 
    //Se conecta al servlet que enviar el documento firmado 
    //URLConnection respuesta = sisdocRet.openConnection(); 

    HttpURLConnection httpcon = (HttpURLConnection) sisdocRet.openConnection(); 
    httpcon.addRequestProperty("User-Agent", "Mozilla/4.76"); 
    httpcon.setRequestProperty("Content-Type", "application/pdf"); 
    httpcon.setDoOutput(true); 
    httpcon.setDoInput(true); 
    httpcon.setUseCaches(false); 

    OutputStream oe = httpcon.getOutputStream(); 

    PdfStamper stp = PdfStamper.createSignature(pdf, oe, '\0'); 
    PdfSignatureAppearance sap = stp.getSignatureAppearance(); 
    sap.setReason("Validez de firma"); 
    sap.setLocation("Costa Rica"); 
    sap.setVisibleSignature(new com.itextpdf.text.Rectangle(0, 0, 80, 80), 1, null); 

    String alias = (String) ks.aliases().nextElement(); 

    //PrivateKey pk = (PrivateKey) ks.getKey("FIRMA", null); 
    java.security.cert.Certificate chain = ks.getCertificate(alias); 

    X509Certificate x509 = (X509Certificate) chain; 
    x509.checkValidity(); 

    ExternalSignature es = new PrivateKeySignature(key, "SHA-1", pkcs11Provider.getName()); 
    ExternalDigest digest = new BouncyCastleDigest(); 
    Certificate[] certs = new Certificate[1]; 
    certs[0] = chain; 

    MakeSignature.signDetached(sap, digest, es, certs, null, null, null, 0, CryptoStandard.CMS); 
    oe.flush(); 
    httpcon.connect(); 
    httpcon.getInputStream(); 
    return "Correcto"; 

回答

4

你做

PdfStamper stp = PdfStamper.createSignature(pdf, oe, '\0'); 

對於早期簽名仍然有效,不過,你必須在附加模式實例化一個PdfStamper

PdfStamper stp = PdfStamper.createSignature(pdf, oe, '\0', null, true); 

(拉斯維加斯t參數選擇追加模式。)

參考後者構造函數的JavaDoc:

/** 
* Applies a digital signature to a document, possibly as a new revision, making 
* possible multiple signatures. The returned PdfStamper 
* can be used normally as the signature is only applied when closing. 
... 
* @param append if <CODE>true</CODE> the signature and all the other content will be added as a 
* new revision thus not invalidating existing signatures 
* @return a <CODE>PdfStamper</CODE> 
* @throws DocumentException on error 
* @throws IOException on error 
*/ 
public static PdfStamper createSignature(final PdfReader reader, final OutputStream os, final char pdfVersion, File tempFile, final boolean append) throws DocumentException, IOException {