Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Adding Visible Electronic Signatures to PDFs

DZone's Guide to

Adding Visible Electronic Signatures to PDFs

While this may be a bit of a narrow topic for developers, a lot of people use this functionality, making it an important aspect of data security and privacy

· Security Zone ·
Free Resource

Discover how to provide active runtime protection for your web applications from known and unknown vulnerabilities including Remote Code Execution Attacks.

I'm aware this is going to be a very niche topic. Electronically signing PDFs is far from a mainstream use case. However, I'll write it for two reasons - first, I think it will be very useful for those few who actually need it, and second, I think it will become more and more common as the eIDAS regulations gain popularity - it basically says that electronic signatures are recognized everywhere in Europe (now, it's not exactly true, because of some boring legal details, but anyway).

So, what is the use case? First, you have to electronically sign the PDF with an a digital signature (the legal term is "electronic signature," so I'll use them interchangeably, although they don't fully match - e.g. any electronic data applied to other data can be seen as an electronic signature, where a digital signature is a PKI-based signature).

Second, you may want to actually display the signature on the pages, rather than have the PDF reader recognize it and show it in some side-panel. Why is that? Because people are used to seeing signatures on pages and some may insist on having the signature visible (true story - I've got a comment that a detached signature "is not a REAL electronic signature because it's not visible on the page").

Now, notice that I wrote "pages," not "page." Yes, an electronic document doesn't have pages - it's a stream of bytes. So having the signature just on the last page is okay. But, again, people are used to signing all pages, so they'd prefer the electronic signature to be visible on all pages.

And that makes the task tricky - PDFs work well with a digital signature box on the last page, but having multiple such boxes doesn't work well. Therefore one has to add other types of annotations that look like a signature box and, when clicked open, the signature panel (just like an actual signature box).

Here, I have to introduce DSS - a wonderful set of components by the European Commission that can be used to sign and validate all sorts of electronic signatures. It's open source, you can use it any way you like. Deploy the demo application, use only the libraries, whatever. It includes the signing functionality out of the box - just check the PAdESService or the PDFBoxSignatureService. It even includes the option to visualize the signature once (on a particular page).

However, it doesn't have the option to show "stamps" (images) on multiple pages. Which is why I forked it and implemented the functionality. Most of my changes are in the PDFBoxSignatureService in the loadAndStampDocument(..) method. If you want to use that functionality you can just build a jar from my fork and use it (by passing the appropriate SignatureImageParameters to PAdESSErvice.sign(..) to define how the signature will look like).

Why is this needed in the first place? Because when a document is signed, you cannot modify it anymore, as you will change the hash. However, PDFs have incremental updates which allow you to append the document and thus having a newer version without modifying anything in the original version. That way the signature is still valid (the originally signed content is not modified), but new stuff is added. In our case, this new stuff is some "annotations," which represent an image and a clickable area that opens the signature panel (in Adobe Reader, at least). And while they are added before the signature box is added, if there is more than one signer, then the second signer's annotations are added after the first signature.

Sadly, PDFBox doesn't support that out of the box. Well, it almost does - the piece of code below looks hacky, and it took a while to figure out how exactly should be called and when, but it works with just a single reflection call:

for (PDPage page : pdDocument.getPages()) {
        // reset existing annotations (needed in order to have the stamps added)
        page.setAnnotations(null);
    }
    // reset document outline (needed in order to have the stamps added)
    pdDocument.getDocumentCatalog().setDocumentOutline(null);
    List<PDAnnotation> annotations = addStamps(pdDocument, parameters);

    setDocumentId(parameters, pdDocument);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try (COSWriter writer = new COSWriter(baos, new RandomAccessBuffer(pdfBytes))) {
        // force-add the annotations (wouldn't be saved in incremental updates otherwise)
        annotations.forEach(ann -> addObjectToWrite(writer, ann.getCOSObject()));

        // technically the same as saveIncremental but with more control
        writer.write(pdDocument);
    }
    pdDocument.close();
    pdDocument = PDDocument.load(baos.toByteArray());
    ...
}

private void addObjectToWrite(COSWriter writer, COSDictionary cosObject) {
    // the COSWriter does not expose the addObjectToWrite method, so we need reflection to add the annotations
    try {
        Method method = writer.getClass().getDeclaredMethod("addObjectToWrite", COSBase.class);
        method.setAccessible(true);
        method.invoke(writer, cosObject);
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

What it does is it loads the original PDF, clears some internal catalogs, adds the annotations (images) to all pages, and then "force-add the annotations" because they "wouldn't be saved in incremental updates otherwise." I hope PDFBox make this a little more straightforward, but for the time being this works, and it doesn't invalidate the existing signatures.

I hope that this post introduced you to:

  • The existence of legally binding electronic signatures.
  • The existence of the DSS utilities.
  • The PAdES standard for PDF signing.
  • How to place more than just one signature box in a PDF document.

And I hope this article becomes more and more popular over time, as more and more businesses realize they could make use of electronic signatures.

Find out how Waratek’s award-winning application security platform can improve the security of your new and legacy applications and platforms with no false positives, code changes or slowing your application.

Topics:
security ,electronic signature ,data security ,data privacy

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}