Digital signatures, OCSP, and timestamping Part 1 (iText 5)

Digital signatures in PDF also involve asymmetric cryptography. Suppose that you receive an official PDF document from Specimen. How do you make sure that this document was originally created by not by somebody else? Also, how do you make sure that nobody changed the document after created it and before you received it?

This encrypted digest will be stored in a signature field. When you open the signed PDF, the viewer application will decrypt the encrypted digest using the author’s public key, and compare it with a newly created digest of the content. If there’s a match, the document wasn’t tampered with; if there’s a difference, somebody else has tried to forge the author’s signature, or the document was changed after it was signed.

Let’s start by creating a document that has a signature field.

Creating an unsigned signature field

When you created AcroForms in topic 8, we discussed button (/Btn), text (/Tx), and choice (/Ch) fields, but we skipped signature fields (/Sig). Figure 12.4 shows two PDF files. The one to the left has a signature field without a digital signature. This file was signed using my own private key. The resulting PDF is shown on the right.

PDFs with signature fields


Figure 12.4 PDFs with signature fields

Listing 12.13 SignatureField.java

Listing 12.13 SignatureField.java

Normally, you won’t have to use the code in listing 12.13. The signature field will either be present because it was added by another application (such as Adobe Acrobat); or you’ll be presented with a document that has no signature field. In that case, you can add the field and sign it at the same time.

Signing a PDF

Listing 12.14 adds a signature to the field created in listing 12.13. There are two options: with the parameter certified, you can choose whether or not to use a certification signature.This is different from what was displayed in figure 12.4, where it only said "Signed and all signatures are valid."

There’s also a graphic parameter to define whether or not to use a graphical object instead of a text message. In figure 12.5, the 1T3XT logo was used to visualize the signature on the page.

This code shows how to add a signature field without a signature.

PDF with a certifying signature

Figure 12.5 PDF with a certifying signature

Listing 12.14 SignatureField.java

Listing 12.14 SignatureField.java

This listing no longer uses the constructor to create an instance of PdfStamper, but the method createSignature() O- You create a PdfSignatureAppearance and define it as a visible signature ©. In this example, the signature field uses the name "mySig".

FAQ How can I sign a document if it doesn’t have a signature field? If there’s no signature field present, you can make a small change to the code from listing 12.14 to add a signature that will show up in the signature panel (see the left side of figure 12.5). If you omit the setVisibleSignature() method, the signature won’t show up on any page. This is called an invisible signature. Or you can use the setVisibleSignature() method with a Rectangle object, a page number, and a field name as parameters. This will create a new signature field.

The name of the person who signs the document is retrieved from the private key. You can add a reason for signing and a location with the setReason() and setLocation() methods G. This information can be used for the appearance in the signature field (see figure 12.4) and it’s also shown in the signature panel (see figure 12.5).

You pass the PrivateKey object and the Certificate chain obtained from the key store to the setCrypto() method Q. With the third parameter, you can pass certificate revocation lists (CRLs). We’ll discuss certificate revocation in section 12.4.6. With the final parameter, you choose a security handler. The corresponding cryptographic filters that are supported in iText are listed in table 12.4.

Table 12.4 Security handlers

iText constant

Filter name

Description

tmp404-66

Adobe.PPKLite

This uses a self-signed security handler.

tmp404-67

VeriSign.PPKVS

To sign documents with the VeriSign CA, you need a key that is certified with VeriSign. You can acquire a 60-day trial key or buy a permanent key at verisign.com.

tmp404-68

Adobe.PPKMS

The Microsoft Windows Certificate Security works with any trusted certificate. For instance, I’m using a public-private key pair obtained from CACert (http://cacert.org).

The signature shown in figure 12.4 is an ordinary signature, aka an approval or a recipient signature. A document can be signed for approval by one or more recipients.

The signature shown in figure 12.5 is a certification signature, aka an author signature. There can only be one certification signature in a document. In iText, you create a certification signature by using the setCertificationLevel() method Q with one of the following values:

CERTIFIED_NO_CHANGES_ALLOWED—No changes are allowed. CERTIFIED_FORM_FILLING—The document is certified, but other people can still fill out form fields without invalidating the signature.

CERTIFIED_FORM_FILLING_AND_ANNOTATIONS—The document is certified, but other people can still fill out form fields and add annotations without invalidating the signature.

If you use NOT_CERTIFIED as parameter, an approval signature will be added.

Just like other form fields, a signature field has an appearance. Only the normal appearance is supported; the rollover and down attributes aren’t used. There are two approaches to generating those appearances. In ©, you use the setAcro6Layers() method and pass the 1T3XT logo as signature graphic with the setSignature-Graphic() method, because listing 12.14 uses the GRAPHIC option for the rendering mode. The following options are available for the setRenderingMode() method:

■ DESCRIPTION—The rendering mode is just the description. NAME_AND_DESCRIPTION—The rendering mode is the name of the signer and the description.

GRAPHIC_AND_DESCRIPTION—The rendering mode is an image and the description.

■ GRAPHIC—The rendering mode is just an image.

The setAcro6Layers() method refers to Acrobat 6. In earlier versions of Acrobat, the signature appearance consisted of five different layers that are drawn on top of each other:

■ n0 —Background layer.

■ n1 —Validity layer, used for the unknown and valid state; contains, for instance, a yellow question mark.

■ n2—Signature appearance, containing information about the signature. This can be text or an XObject that represents the handwritten signature.

■ n3—Validity layer, containing a graphic that represents the validity of the signature when the signature is invalid.

■ n4—Text layer, for a text presentation of the state of the signature.

If you omit setAcro6Layers(), iText will create a default appearance for these layers, or you can use the method getLayer() with a number ranging from 0 to 4 to get a PdfTemplate that allows you to create a custom appearance. You can also use the methods setLayer2Text() and setLayer4Text() to add a custom text for the signature appearance and the text layer. Note that the use of layers n1, n3, and n4 is no longer recommended since Acrobat 6.

In the next example, you’ll add more than one signature.

Adding multiple signatures

Figure 12.6 shows another Hello World document, but now it has been signed twice. Once by myself with a signature that could be validated, and once by Specimen, who isn’t trusted because "None of the parent certificates are trusted identities." This is normal: the certificate was self-signed; there was no CA such as VeriSign involved.

If you know and trust Specimen, you can add his public certificate to the list of trusted identities in Adobe Reader. You can import the file foobar.cer through Document > Manage Trusted Identities and edit the trust as a "trusted root." If you do, the second signature can also be verified (figure 12.7).

Document with two signatures, one of which has "validity unknown"

Figure 12.6 Document with two signatures, one of which has "validity unknown"

Document with two valid signatures

Figure 12.7 Document with two valid signatures

The original Hello World example of the document shown in figures 12.6 and 12.7 didn’t have a signature field. Here is how the first signature was added.

Listing 12.15 Signatures.java

Listing 12.15 Signatures.javaListing 12.15 Signatures.java

You don’t have to create a PdfFormField explicitly as in listing 12.13. The field is created by iText using the parameters of the setVisibleSignature() method. Note that this time you add an Image that will be added in the background of layer 2. Compare listing 12.15 with this one to find out how to add a second approval signature.

Listing 12.16 Signatures.java

Listing 12.16 Signatures.java

You have to add two extra parameters to the createSignature() method if you want to add a second signature. One parameter can be used to store the resulting PDF as a temporary file. If you pass a File object that’s a directory, a temporary file will be created there; if it’s a file, it will be used directly. The file will be deleted on exit unless the os output stream is null. In that case, the document can be retrieved directly from the temporary file. This is a way to keep the memory use low. In this example, you’re signing a simple Hello World file. You don’t need a temporary file; the signing will be done in memory.

The fifth parameter of createSignature() indicates whether or not the file has to be manipulated in append mode. Working in append mode means that the original file will be kept intact; the new content will be appended after the %EOF marker.

NOTE You can also use append mode if you want the file to keep the complete history of the changes made to the document. We’ll look at the implications of using append mode outside the context of digital signatures in topic 13.

Using append mode is mandatory if you want to add content to a document that has been signed. If you set the append value to false, the original signature will be invalidated, as shown in figure 12.8.

When a document is signed multiple times, you get a PDF file with multiple revisions (see the signature panel in figures 12.6 and 12.7). For one revision, the signature name is "first"; for the other it’s "second". In figure 12.6, you can see a link in the signature panel saying "Click to view this version." This allows you to manually retrieve the original files for each signature. This listing shows how to extract such a revision programmatically.

Document with one valid and one invalid signature

Figure 12.8 Document with one valid and one invalid signature

Listing 12.17 Signatures.java

Listing 12.17 Signatures.java

With this code snippet, you can extract the first revision, the one that only has the signature field named "first".

We’ve now checked for the validity of a signature using Adobe Reader, but you can also automate the process.

Next post:

Previous post: