我正在使用 iText 的方法使用数字证书对 PDF 进行签名,并使用 PdfSignatureAppearance 生成文档中可见的签名,但我希望可见的签名不要打印出来。我看到 PdfAnnotation 类中有类似的东西,您可以在其中为此添加一个标志。有没有办法用数字签名来做到这一点? 我的代码:
PdfStamper stp = null;
try {
PdfReader reader = new PdfReader(pdfInputFileName);
stp = PdfStamper.createSignature(reader, fout, '\0');
PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setCrypto(privateKey, certificateChain, null, PdfSignatureAppearance.WINCER_SIGNED);
sap.setReason(reason);
sap.setLocation(location);
sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
sap.setVisibleSignature(new Rectangle(30, 830, 170, 770), 1, null);
stp.close();
} catch (DocumentException | IOException e) {
logger.error("An unknown error accoured while signing the PDF file: " + e.getMessage());
}
这是由该代码签名的 PDF 的链接,当我打印它时,签名印章总是出现在打印中: https://s3.amazonaws.com/gxzadminlocal/anexo_28276.pdf
最佳答案
如果签名字段尚不存在并且必须创建它,当前的 iText 5 版本会自动设置 PRINT 标志。但是,如果您填写现有的签名字段,则该标志不会受到影响。因此,您可能希望在第一步中添加一个没有 PRINT 标志的空签名字段,并在第二步中使用该字段进行签名,例如使用以下代码:
准备 PDF
您可以准备一个带有空签名字段的 PDF 而无需设置 PRINT 标志,如下所示:
try ( InputStream resource = SOURCE_STREAM;
OutputStream os = INTERMEDIATE_OUTPUT_STREAM) {
PdfReader reader = new PdfReader(resource);
PdfStamper stamper = new PdfStamper(reader, os);
PdfFormField field = PdfFormField.createSignature(stamper.getWriter());
field.setFieldName("Signature");
field.setWidget(new Rectangle(30, 830, 170, 770), PdfAnnotation.HIGHLIGHT_NONE);
stamper.addAnnotation(field, 1);
stamper.close();
}
( CreateSignature 测试 signWidgetNoPrint
通过 1)
特别是你不这样做
field.setFlags(PdfAnnotation.FLAGS_PRINT);
这里!
签署准备好的 PDF
创建中间 PDF 后,您可以按如下方式对其进行签名:
try ( InputStream resource = INTERMEDIATE_INPUT_STREAM;
OutputStream os = RESULT_STREAM) {
PdfReader reader = new PdfReader(resource);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason("reason");
appearance.setLocation("location");
appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
appearance.setVisibleSignature("Signature");
ExternalSignature pks = new PrivateKeySignature(pk, "SHA512", "BC");
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, pks, chain, null, null, null, 0, CryptoStandard.CMS);
}
( CreateSignature 测试 signWidgetNoPrint
通过 2)
假设您已在pk
中准备好私钥,在chain
中准备好证书链;并假设您已将 Bouncy CaSTLe 注册为安全提供商。
在结果 PDF 中,签名可视化显示在屏幕上,但不会打印出来。
关于使用 iText 的 Java PDF 数字签名可见,但不可打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53193048/