I'm using iText's methods to sign a PDF with digital certificate, generating a signature visible in the document with PdfSignatureAppearance, but I'd like the visible signature not to come out in print. I saw that there is something similar in the PdfAnnotation class, where you can add a flag for this. Is there any way to do this with the digital signature? My code:
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());
}
This is the link to a PDF signed by this code, when I print it, the signature stamp always comes out in the print: https://s3.amazonaws.com/gxzadminlocal/anexo_28276.pdf
Current iText 5 versions automatically set the PRINT flag if the signature field does not yet exist and they have to create it. But if you fill an existing signature field, that flag is untouched. Thus, you might want to add an empty signature field without that PRINT flag in a first step and in a second step sign using that field, e.g. with the following code:
You can prepare a PDF with an empty signature field without setting the PRINT flag like this:
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 test signWidgetNoPrint
pass 1)
In particular you don't do
field.setFlags(PdfAnnotation.FLAGS_PRINT);
here!
Having created that intermediate PDF, you can sign it like this:
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 test signWidgetNoPrint
pass 2)
assuming you have prepared your private key in pk
and your certificate chain in chain
; and assuming you have registered Bouncy Castle as security provider.
In the result PDF the signature visualization appears on screen but not in print.