This article explores how digital signatures in PDF work and how to digitally sign the PDF document when signature is created in remote app, device or service. In the end you will also find references that will help you implement external PDF digital signatures. More details from ETSI 319 142-1
There are 2 main types of digital signatures in PDF. Older standard PKCS7 or adbe.pkcs7.detached and eIDAS specification compliant ETSI.CAdES.detached. Main difference is that ETSI.CAdES.detached is more strict and concrete, for example CAdES signatures cover whole PDF except the immediate signature value bytes. PKCS #7 signature in that sense is more relaxed and its possible to change more things in PDF without invalidating digital signatures.
PDF files support multiple digital signatures in one file and they are all serial. Meaning that you can add new digital signature once first one is completed. As soon as first digital signature is added then all changes to PDF are saved incrementally meaning new revision of PDF is done for every new signature and new signature data is added to the end of the file.
In generally its not possible to change PDF contents or appearance after first digital signature. However it’s worth mentioning that you can even change the PDF appearance after first digital signature when you incorporate visual signature to following digital signatures. Visual signature part is not mandatory but in some cases people want to look into something to feel more calm. All the “signature” part is still in the invisible cryptography.
Adding digital signatures to PDF consists of 2 steps.
- Create signature dictionary and reserve ByteRange. Initially all signature content bytes are zeros.
- Generate signature value “somehow” and write signature contents in hex into the beginning of the reserved ByteRange
If you open the digitally signed PDF file with text editor then you will see something like this.
<< /Type /Sig /Filter /Adobe.PPKLite /SubFilter /ETSI.CAdES.detached /Name (My Name) /ContactInfo (email@example.com) /Location (At my desk) /Reason (Signed in test app) /M (D:20210105184421+00'00') /Contents <30822C....CFE000....000000> /ByteRange [0 3991 41881 794] >>
ByteRange in here means that PDF contents are starting from byte 0 with length 3991 and starting from 41181 another 794 bytes. Between the 3991 and 41181 is the signature value. To verify the digital signature we will take the signature, cut out bytes from 3991-41181 and then calculate the digest to verify the detached signature against. This means that this part including angle brackets will be removed <30822C….CFE000….000000>
Since we do not know exactly how long the signature will be then we need to reserve big enough ByteRange. RSA and Ellicptic Curve signatures are different length. In EC digital signatures signature lenth depends also on the exact curve secp384r1 or prime256v1 etc. In addition the digital signature can contain also timestamp which further increases the size. As a consequence the end of the ByteRange will always be some number of zeros.
Source code for this app can be found from https://github.com/eideasy/eideasy-external-pades-digital-signatures. Docker machine in docker hub is located at https://hub.docker.com/repository/docker/eideasy/pades-external-digital-signatures. There is even free application running for testing purposes at https://detached-pdf.eideasy.com
In case you would want help with creating qualified digital signatures with national eID cards, Mobile-ID, Smart-ID, ZealID or similar apps then you can look into this set of API-s https://documenter.getpostman.com/view/3869493/Szf6WoG1