我想签名并添加LTV但尚未签名的PDF。
我已经从iText示例和qustions中复制了编码 http://developers.itextpdf.com/question/how-enable-ltv-timestamp-signature
主要方法的基本部分:
Security.addProvider(new BouncyCastleProvider());
EncryptPDF pdf = new EncryptPDF();
OCSPVerifier ocspVerifier = new OCSPVerifier(null, null);
OcspClient ocsp = new OcspClientBouncyCastle(ocspVerifier);
pdf.signPDF(file_src, file_temp, ocsp);
pdf.addLtvNoTS(file_temp, file_dest, ocsp);
方法signPDF签名没有问题(或现在注释加密)。临时文件没问题。
private void signPDF(String src, String dest, OcspClient ocsp) {
try {
PdfReader reader = new PdfReader(src);
KeyStore ks = KeyStore.getInstance("pkcs12", "BC");
ks.load(new FileInputStream(cert2_src), keystore_password.toCharArray());
String alias = null;
Enumeration<String> en = ks.aliases();
while(en.hasMoreElements()) {
alias = en.nextElement();
System.out.println("alias name: " + alias);
}
PrivateKey pk = (PrivateKey) ks.getKey(alias, key_password.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
PdfStamper stamper = PdfStamper.createSignature(reader, new FileOutputStream(dest), '\0', null, true);
// appearance
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setImage(Image.getInstance(res_src));
appearance.setVisibleSignature(new Rectangle(172, 132, 572, 232), 1, "SignatureField");
// Certificate cert = getPublicCertificate(cert_src);
// stamper.setEncryption(new Certificate[]{cert},
// new int[]{PdfWriter.ALLOW_PRINTING}, PdfWriter.ENCRYPTION_AES_128 ); //| PdfWriter.DO_NOT_ENCRYPT_METADATA
// digital signature
ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "BC");
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, es, chain, null, ocsp, null, 0, CryptoStandard.CMS);
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
在方法addLtvNoTS中我收到错误&#34;签名已定义。必须在PdfSignatureAppearance中关闭。&#34;在最后一行stamper.close()。我无法解决这个问题。请帮忙。
private void addLtvNoTS(String src, String dest, OcspClient ocsp)
throws IOException, DocumentException, GeneralSecurityException {
PdfReader r = new PdfReader(src);
FileOutputStream fos = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(r, fos, '\0', null, true);
LtvVerification v = stamper.getLtvVerification();
AcroFields fields = stamper.getAcroFields();
ArrayList<String> names = fields.getSignatureNames();
String sigName = names.get(names.size() - 1);
PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
v.addVerification(sigName, ocsp, null,
LtvVerification.CertificateOption.WHOLE_CHAIN,
LtvVerification.Level.OCSP,
LtvVerification.CertificateInclusion.NO);
stamper.close();
}
答案 0 :(得分:2)
您的addLtvNoTS
方法似乎首先是文章中addLtv
方法的副本,然后您不完全编辑该方法,以成为addLtvNoTS
方法的副本。
特别是您的addLtvNoTS
方法仍然包含文章addLtv
方法
PdfStamper stamper = PdfStamper.createSignature(r, fos, '\0', null, true);
在文章addLtvNoTS
方法中,相应的行是:
PdfStamper stp = new PdfStamper(r, fos, '\0', true);
因此,您创建了一个PdfStamper
用于签名或时间戳(因此iText最终会抱怨您不这样做),而您应该创建一个不是。