Reputation: 21
Usecase: I'm working on a feature that requires attaching an image to a PDF without invalidating a pre-existing digital signature. The PDF should have a form field designated for image attachment, which can be populated later. I want to implememnt this using PDFBox.
Implementation: Since PDFs lack a dedicated image form field, I’m utilizing a PDPushButton as a workaround, following the method outlined in these resources;
Additionally, the PDF includes a signature form field. The process involves signing the signature field first and subsequently attaching the image to the PDPushButton field. However, this sequence is causing the signature to become invalid.
Here is the code for attaching an image to the PDPushButton.
@SneakyThrows
public static void fillInitialField(String inputFilePath, String outputFilePath) {
// Load input file
PDDocument document = PDDocument.load(new File(inputFilePath));
// Find and link the relevant signature field
PDPushButton initial = PdfService.findInitial(document, "132323423180965");
PDImageXObject pdImageXObject = PDImageXObject.createFromFile("initial.png", document);
float width = 10 * pdImageXObject.getWidth();
float height = 10 * pdImageXObject.getHeight();
PDAppearanceStream pdAppearanceStream = new PDAppearanceStream(document);
pdAppearanceStream.setResources(new PDResources());
try (PDPageContentStream pdPageContentStream = new PDPageContentStream(document, pdAppearanceStream)) {
pdPageContentStream.drawImage(pdImageXObject, 200, 300, width, height);
}
pdAppearanceStream.setBBox(new PDRectangle(width, height));
List<PDAnnotationWidget> widgets = initial.getWidgets();
for (PDAnnotationWidget pdAnnotationWidget : widgets) {
PDAppearanceDictionary pdAppearanceDictionary = pdAnnotationWidget.getAppearance();
if (pdAppearanceDictionary == null) {
pdAppearanceDictionary = new PDAppearanceDictionary();
pdAnnotationWidget.setAppearance(pdAppearanceDictionary);
}
pdAppearanceDictionary.setNormalAppearance(pdAppearanceStream);
}
initial.setReadOnly(true);
// Save and close the document
FileOutputStream fos = new FileOutputStream(outputFilePath);
document.save(fos);
document.close();
}
I’ve created a repository that replicates this issue, which can be found here: https://github.com/ContractSPAN/ImageFormFieldIssue
How can I implement an image attachment to a PDF form field in such a way that it doesn’t invalidate an existing signature? I am open to alternative approaches to achieve this functionality.
Upvotes: 1
Views: 215
Reputation: 11876
You don't need to add a form field either an additional stamped comment or a second signature in any format is permissible, in most localities. The contract is simply formed by the marks of two named parties.
Basically in my area:
Under English law, what constitutes a signature is flexible. A person's intention can determine whether they have entered into binding agreements or transactions. Many electronic signature platforms can establish enough evidence to prove intention, should someone later dispute the validity of the contract. This includes, we believe, for creating a deed under English law.
Electronic signatures should not be relied upon in all circumstances
Both these documents may have exactly the same legal status as signed. Since a signature in any format is permissible in many jurisdictions. The electronic uses of a digital hash is not to be an impediment to intent to form a contract.
Wet signature as a image may be applied on behalf of any other person and form a binding agreement, until one or other party rescinds by informing the other. This is very much an OPT OUT process, similar to King John declaring eight centuries ago, his seal placed for him on Magna Carta Libertatum was not binding per the eyes of his God and thus the charter was annulled by Pope Innocent III!
So what are the requirements? Well technically as it is an "opt out policy" both signatures can be flagged as invalid and still be legally binding as intent of both parties, thus electronic validity is no proof nor denial of intent.
Upvotes: 0
Reputation: 96039
You do a regular save
at the end of fillInitialField
. A regular save will re-arrange and change the signed byte range. Thus, you instead will need to do a saveIncremental
like you do at the end of sign
.
Beware, though, a saveIncremental
in pdfbox 2 requires you to mark (setNeedToBeUpdated(true)
) all changed objects including a sequence of objects leading to them respectively from the trailer. In case of signing, a lot of that marking already is done by PDFBox itself. But in your fillInitialField
method you'll have to do all the marking yourself.
Upvotes: 2