A digital signature is cryptographically secure and verifies that someone with your private signing key (in other words, you) has seen the document and authorized it.
The visual representation of a digital signature in a PDF
document is a widget annotation. A widget annotation is a specific type of annotation.
In PDF
, you have the actual content of a page. This content is stored in a content stream. A page is defined in a page dictionary. There's a /Contents entry in this page dictionary that refers to one of more content streams. Together these content streams contain the syntax that describes the content of a page.
Annotations are not part of any of those streams. Annotations are referred to from the page dictionary using the /Annots entry. In your case, there is an /Annots entry that refers to a widget annotation with the appearance of your signature.
You can read more about PDF
digital signatures here
but before continue let's first talk about some key concepts.
1 Introduction
1.1 Private key
To sign a PDF
document you need to access the private key. But sometimes this can not be safe.
How do I get a private key that is on my smart card ? There would be a serious security problem if you could extract a private key from a smart card. Your private key is secret, and the smart card should be designed to keep this secret safe. You don’t want an external application to use your private key. Instead, you send a hash to the card, and the card returns a signature or a PKCS#7 message. PKCS refers to a group of Public Key Cryptography Standards, and PKCS#7 defines the Cryptographic Message Syntax Standard.
Signing a PDF
document using a smart-card reader involves middleware, and the code will
depend on the type of smart-card reader you’re using. To get an idea of what needs to be
done, we’ll look at some examples where the digest is made or signed externally.
Now let’s discuss some technologies that provide extra security features.
1.2 CRLs, OCSP, and timestamping
Suppose you receive a contract from person X who works at company Y. You can safely assume that the document is genuine, unless … person X was fired, but he still owns a copy of the private key of company Y. Such a contract probably wouldn’t be legal. Surely there must be a way for company Y to revoke the certificate for employee X so that he no longer can act on behalf of his former company.
1.2.1 Certificate Revocation List (CRL)
Every certificate authority keeps lists of certificates that are no longer valid, whether because the owner thinks the private key was compromised, or the token containing the private key was lost or stolen, or the original owner of the key is no longer entitled to use it. Such a list is called a certificate revocation list (CRL), and they are made public at one or more URLs provided by the CA who signed the certificate.
An array of CRL objects can be passed as a parameter to the sign method. However, CRLs are generally large, and this technique is considered to be "old technology."
It might be a better idea to use the Online Certificate Status Protocol (OCSP).
1.2.2 Online Certificate Status Protocol (OCSP)
OCSP is an internet protocol for obtaining the revocation status of a certificate online. You can post a request to check the status of a certificate over HTTP, and the CA’s OCSP server will send you a response. You no longer need to parse and embed long CRLs. An OCSP response is small and constant in size, and can easily be included in the PKCS#7 object.
Revocation information in a PDF
document is a signed attribute, which means that the signing software
must capture the revocation information before signing. A similar requirement in this use case applies
to the chain of certificates. The signing software must capture and validate the certificate’s chain
before signing. CRLs will lead to bigger PDF
documents, and using OCSP will not take as much space.
But the OCSP connection to check the status can take time, whereas CRLs can easily be cached on the
filesystem. It’s always a tradeoff.
Now let’s look at another problem that might arise. Suppose somebody sends you a signed contract. He has used a private key that is still valid, and you’re sure that the document you’ve received is genuine. However, at some point the author of the document regrets what he’s written. By resetting the clock on his computer, he could create a new document with a new digital signature that is as valid as the first one. This way, you could end up with two documents signed with the same private key at almost the same time, but with slightly different content. How can anybody know which document is more genuine?
1.2.3 Timestamping
This problem can be solved by involving a third party: a timestamping authority (TSA). The TSA will take the hash of the document and concatenate a timestamp to it. This is done on a timestamp server that is contacted during the signing process. The time-stamp server will return a hash that is signed using the private key of the TSA.
2 Sign
You can sign a PDF
document using PDFSignOptions
configurator.
<script> var ksm = new Ax.ks.KeyStoreManager("https://bitbucket.org/deister/axional-docs-resources/raw/master/KeyStores/swview/jks-files/jack.jks", "secret"); var pdf = new Ax.pdf.Signer(new Ax.net.URL('https://bitbucket.org/deister/axional-docs-resources/raw/master/PDF/scanned.pdf')); var out = pdf.sign(ksm.getKeyStore(), "jack", "moon", options => { // Top left corner options.setRectangle(10, 748, 220, 780); options.setReason("The reason"); options.setLocation("The location"); // Provide a image options.setImage(Ax.util.Base64.decode('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')); // DESCRIPTION, NAME_AND_DESCRIPTION, GRAPHIC_AND_DESCRIPTION, GRAPHIC options.setRenderingMode("GRAPHIC_AND_DESCRIPTION"); // Add a Timestamp server (free) or add user and password for a protected one options.setTSAClientURL("https://freetsa.org/tsr"); }); new Ax.io.File("/tmp/signed.pdf").write(out); </script>

3 Verify
Verify on a PDF
returns a JSON (map) with PKCS#7 properties. The field verify
will be true if the signature checks out, false otherwise. Other fields are part of
PKCS#7 properties.
<script> var pdf = new Ax.pdf.Signer(new Ax.io.File("/tmp/signed.pdf")); var info = pdf.verify(); for (var key of info.keySet()) { console.log(Ax.lang.String.format("%20s: %s", key, info.get(key))); } </script>
reason: The reason
tsa: 4: O=Free TSA,OU=TSA,2.5.4.13=This certificate digitally signs documents and time stamp requests made using the freetsa.org online services,CN=www.freetsa.org,E=busilezas@gmail.com,L=Wuerzburg,C=DE,ST=Bayern
signName: null
isTST: false
issuerDN: C=LK,ST=Western,L=Colombo,O=Software View,OU=Training,CN=Software View Certificate Authority
name: Signature1
isRevocationValid: false
verify: true
location: The location
digestAlgorithm: SHA256withRSA
signDate: Wed May 01 12:28:11 CEST 2019
subjectDN: C=LK,ST=Western,L=Colombo,O=Software View,OU=Training,CN=Jack Daniel