我需要知道如何在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";
答案 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 {