重复签名PDF

时间:2014-03-04 19:10:46

标签: java itext digital-signature

我需要知道如何在java中多次签署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";

1 个答案:

答案 0 :(得分:4)

你做

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

为了使早期签名保持有效,您必须在追加模式下实例化PdfStamper

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

(最后一个参数选择追加模式。)

比照。后一个构造函数的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 {