Digitally Signing PDF Documents

Digital signatures can be applied to PDF documents to provide a level of security. Digital signatures, like handwritten signatures, provide a means by which signers identify themselves and make statements about a document. The technology used to digitally sign documents helps to ensure that both the signer and recipients are clear about what was signed and confident that the document was not altered since it was signed.

PDF documents are signed by means of public-key technology. A signer has two keys: a public key and a private key. The private key is stored in a user’s credential that must be available at the time of signing. The public key is stored in the user’s certificate that must be available to recipients to validate the signature. Information about revoked certificates is found in certificate revocation lists (CRLs) and Online Certificate Status Protocol (OCSP) responses distributed by Certificate Authorities (CAs). The time of signing can be obtained from a trusted source known as a Timestamping Authority.

Note: Before you can digitally sign a PDF document, you must ensure that you add the certificate to LiveCycle. A certificate is added using Administration Console or programmatically using the Trust Manager API. (See Importing Credentials by using the Trust Manager API.)

You can programmatically digitally sign PDF documents. When digitally signing a PDF document, you must reference a security credential that exists in LiveCycle. The credential is the private key used for signing.

The Signature service performs the following steps when a PDF document is signed:

  1. The Signature service retrieves the credential from the Truststore by passing the alias specified in the request.

  2. The Truststore searches for the specified credential.

  3. The credential is returned to the Signature service and is used to sign the document. The credential is also cached against the alias for future requests.

For information about handling the security credential, see the Installing and Deploying LiveCycle guide for your application server.

Note: There are differences between signing and certifying documents. (See Certifying PDF Documents.)
Note: Not all PDF documents support signing. For more information about the Signature service and digitally signing documents, see Services Reference for LiveCycle.
Note: The Signature service does not support XDP files with embedded PDF data as input to an operation, such as certifying a document. This action results in the Signature service throwing a PDFOperationException. To resolve this issue, convert the XDP file to a PDF file by using the PDF Utilities service and then pass the converted PDF file to a Signature service operation. (See Working with PDF Utilities.)

nCipher nShield HSM credential

When using an nCipher nShield HSM credential to sign or certify a PDF document, the new credential cannot be used until the J2EE application server that LiveCycle is deployed on is restarted. However, you can set a configuration value, resulting in the sign or certify operation working without restarting the J2EE application server.

You can add the following configuration value in the cknfastrc file, which is located at /opt/nfast/cknfastrc (or c:\nfast\cknfastrc):

CKNFAST_ASSUME_SINGLE_PROCESS=0 

After you add this configuration value to the cknfastrc file, the new credential can be used without restarting the J2EE application server.

Signature is not trusted

When certifying and signing the same PDF document, if the certifying signature is not trusted, a yellow triangle appears against the first signature when opening the PDF document in Acrobat or Adobe Reader. The certifying signature must be trusted in order to avoid this situation.

Signing documents that are XFA based forms

If you attempt to sign a XFA based form using the Signature service API, the data may be missing from the ViewSignedVersion located in Acrobat. For example, consider the following workflow:

  • Using an XDP file created by using Designer, you merge a form design that contains a signature field and XML data that contains form data. You use the Forms service to generate an interactive PDF document.

  • You sign the PDF document using the Signature service API.

Summary of steps

To digitally sign a PDF document, perform the following tasks:

  1. Include project files.

  2. Create a Signature service client.

  3. Get the PDF document to sign.

  4. Sign the PDF document.

  5. Save the signed PDF document as a PDF file.

Include project files

Include necessary files into your development project. If you are creating a client application using Java, include the necessary JAR files. If you are using web services, ensure that you include the proxy files.

The following JAR files must be added to your project’s classpath:

  • adobe-livecycle-client.jar

  • adobe-usermanager-client.jar

  • adobe-signatures-client.jar

  • adobe-utilities.jar (required if LiveCycle is deployed on JBoss)

  • jbossall-client.jar (required if LiveCycle is deployed on JBoss)

Create a Signatures client

Before you can programmatically perform a Signature service operation, you must create a Signature service client.

Get the PDF document to sign

To sign a PDF document, you must obtain a PDF document that contains a signature field. If a PDF document does not contain a signature field, it cannot be signed. A signature field can be added by using Designer or programmatically.

Sign the PDF document

When signing a PDF document, you can set run-time options that are used by the Signature service. You can set the following options:

  • Appearance options

  • Revocation checking

  • Time stamping values

You set appearance options by using a PDFSignatureAppearanceOptionSpec object. For example, you can display the date within a signature by invoking the PDFSignatureAppearanceOptionSpec object’s setShowDate method and passing true.

You can also specify whether or not to perform a revocation check that determines whether the certificate that is used to digitally sign a PDF document has been revoked. To performing revocation checking, you can specify one of the following values:

  • NoCheck: Do not perform revocation checking.

  • BestEffort: Always attempt to check for revocation of all certificates in the chain. If any problem occurs in checking, the revocation is assumed to be valid. If any failure happens, assume that the certificate is not revoked.

  • CheckIfAvailable: Check for revocation of all certificates in the chain if revocation information is available. If any problem occurs in checking, the revocation is assumed to be invalid. If any failure happens, assume the certificate is revoked and invalid. (This is the default value.)

  • AlwaysCheck: Check for revocation of all certificates in the chain. If revocation information is not present in any certificate, revocation is assumed to be invalid.

To perform revocation checking on a certificate, you can specify a URL to a certificate revocation list (CRL) server by using a CRLOptionSpec object. However, if you want to perform revocation checking and you do not specify a URL to a CRL server, then the Signature service obtains the URL from the certificate.

Instead of using a CRL server, you can use an online certificate status protocol (OCSP) server when performing revocation checking. Typically when using an OCSP server as opposed to a CRL server, the revocation check is performed faster. (See “Online Certificate Status Protocol” at http://tools.ietf.org/html/rfc2560.)

You can set the CRL and OCSP server order that the Signature service uses using Adobe Applications and Services. For example, if the OCSP server is set first in Adobe Applications and Services, then the OCSP server is checked, followed by the CRL server. (See “Managing certificates and credentials using Trust Store“ in AAC Help).

If you specify not to perform revocation checking, then the Signature service does not check to see if the certificate used to sign or certify a document has been revoked. That is, CRL and OCSP server information is ignored.

Note: Although a CRL or an OCSP server may be specified in the certificate, you can override the URL specified in the certificate by using a CRLOptionSpec and an OCSPOptionSpec object. For example, to override the CRL server, you can invoke the CRLOptionSpec object’s setLocalURI method.

Time stamping refers to the process of tracking the time when a signed or certified document was modified. Once a document is signed, it should not be modified, even by the document owner. Time stamping helps enforce the validity of a signed or certified document. You can set time stamping options using a TSPOptionSpec object. For example, you can specify the URL of a time stamping provider (TSP) server.

Note: In the Java and web service walk through sections and the corresponding quick starts, revocation checking is used. Because no CRL or OCSP server information is specified, the server information is obtained from the certificate used to digitally sign the PDF document.

To successfully sign a PDF document, you can specify the fully qualified name of the signature field that will contain the digital signature, such as form1[0].#subform[1].SignatureField3[3]. When using an XFA form field, the partial name of the signature field can also be used: SignatureField3[3].

You must also reference a security credential to digitally sign a PDF document. To reference a security credential, you specify an alias. The alias is a reference to an actual credential that may be in a PKCS#12 file (with a .pfx extension), or a hardware security module (HSM). For information about the security credential, see the Installing and Deploying LiveCycle guide for your application server.

Save the signed PDF document

After the Signature service digitally signs the PDF document, you can save it as a PDF file so that users can open it in Acrobat or Adobe Reader.

Digitally sign PDF documents using the Java API

Digitally sign a PDF document by using the Signature API (Java):

  1. Include project files

    Include client JAR files, such as adobe-signatures-client.jar, in your Java project’s classpath.

  2. Create a Signatures client

    • Create a ServiceClientFactory object that contains connection properties.

    • Create a SignatureServiceClient object by using its constructor and passing the ServiceClientFactory object.

  3. Get the PDF document to sign

    • Create a java.io.FileInputStream object that represents the PDF document to digitally sign by using its constructor and passing a string value that specifies the location of the PDF document.

    • Create a com.adobe.idp.Document object by using its constructor and passing the java.io.FileInputStream object.

  4. Sign the PDF document

    Sign the PDF document by invoking the SignatureServiceClient object’s sign method and passing the following values:

    • A com.adobe.idp.Document object that represents the PDF document to sign.

    • A string value that represents the name of the signature field that will contain the digital signature.

    • A Credential object that represents the credential that is used to digitally sign the PDF document. Create a Credential object by invoking the Credential object’s static getInstance method and passing a string value that specifies the alias value that corresponds to the security credential.

    • A HashAlgorithm object that specifies a static data member that represents the hash algorithm to use to digest the PDF document. For example, you can specify HashAlgorithm.SHA1 to use the SHA1 algorithm.

    • A string value that represents the reason why the PDF document was digitally signed.

    • A string value that represents the signer’s contact information.

    • A PDFSignatureAppearanceOptions object that controls the appearance of the digital signature. For example, you can use this object to add a custom logo to a digital signature.

    • A java.lang.Boolean object that specifies whether to perform revocation checking on the signer's certificate.

    • An OCSPOptionSpec object that stores preferences for Online Certificate Status Protocol (OCSP) support. If revocation checking is not done, this parameter is not used and you can specify null.

    • A CRLPreferences object that stores certificate revocation list (CRL) preferences. If revocation checking is not done, this parameter is not used and you can specify null.

    • A TSPPreferences object that stores preferences for time stamp provider (TSP) support. This parameter is optional and can be null. For more information, see LiveCycle API Reference.

    The sign method returns a com.adobe.idp.Document object that represents the signed PDF document.

  5. Save the signed PDF document

    • Create a java.io.File object and ensure that the file extension is .pdf.

    • Invoke the com.adobe.idp.Document object’s copyToFile method and pass java.io.File to copy the contents of the Document object to the file. Ensure that you use the com.adobe.idp.Document object that was returned by the sign method.

Digitally signing PDF documents using the web service API

To digitally sign a PDF document by using the Signature API (web service):

  1. Include project files

    Create a Microsoft .NET project that uses MTOM. Ensure that you use the following WSDL definition: http://localhost:8080/soap/services/SignatureService?WSDL&lc_version=9.0.1.

    Note: Replace localhost with the IP address of the server hosting LiveCycle.
  2. Create a Signatures client

    • Create a SignatureServiceClient object by using its default constructor.

    • Create a SignatureServiceClient.Endpoint.Address object by using the System.ServiceModel.EndpointAddress constructor. Pass a string value that specifies the WSDL to the LiveCycle service (for example, http://localhost:8080/soap/services/SignatureService?WSDL). You do not need to use the lc_version attribute. This attribute is used when you create a service reference.)

    • Create a System.ServiceModel.BasicHttpBinding object by getting the value of the SignatureServiceClient.Endpoint.Binding field. Cast the return value to BasicHttpBinding.

    • Set the System.ServiceModel.BasicHttpBinding object’s MessageEncoding field to WSMessageEncoding.Mtom. This value ensures that MTOM is used.

    • Enable basic HTTP authentication by performing the following tasks:

      • Assign the LiveCycle user name to the field SignatureServiceClient.ClientCredentials.UserName.UserName.

      • Assign the corresponding password value to the field SignatureServiceClient.ClientCredentials.UserName.Password.

      • Assign the constant value HttpClientCredentialType.Basic to the field BasicHttpBindingSecurity.Transport.ClientCredentialType.

      • Assign the constant value BasicHttpSecurityMode.TransportCredentialOnly to the field BasicHttpBindingSecurity.Security.Mode.

  3. Get the PDF document to sign

    • Create a BLOB object by using its constructor. The BLOB object is used to store a PDF document that is signed.

    • Create a System.IO.FileStream object by invoking its constructor and passing a string value that represents the file location of the PDF document to sign, and the mode in which to open the file.

    • Create a byte array that stores the content of the System.IO.FileStream object. You can determine the size of the byte array by getting the System.IO.FileStream object’s Length property.

    • Populate the byte array with stream data by invoking the System.IO.FileStream object’s Read method and passing the byte array, the starting position, and the stream length to read.

    • Populate the BLOB object by assigning its MTOM property the contents of the byte array.

  4. Sign the PDF document

    Sign the PDF document by invoking the SignatureServiceClient object’s sign method and passing the following values:

    • A BLOB object that represents the PDF document to sign.

    • A string value that represents the name of the signature field that will contain the digital signature.

    • A Credential object that represents the credential that is used to digitally sign the PDF document. Create a Credential object by using its constructor and specify the alias by assigning a value to the Credential object’s alias property.

    • A HashAlgorithm object that specifies a static data member that represents the hash algorithm to use to digest the PDF document. For example, you can specify HashAlgorithm.SHA1 to use the SHA1 algorithm.

    • A Boolean value that specifies whether the hash algorithm is used.

    • A string value that represents the reason why the PDF document was digitally signed.

    • A string value that represents the signer’s location.

    • A string value that represents the signer’s contact information.

    • A PDFSignatureAppearanceOptions object that controls the appearance of the digital signature. For example, you can use this object to add a custom logo to a digital signature.

    • A System.Boolean object that specifies whether to perform revocation checking on the signer's certificate. If this revocation checking is done, it is embedded in the signature. The default is false.

    • An OCSPOptionSpec object that stores preferences for Online Certificate Status Protocol (OCSP) support. If revocation checking is not done, this parameter is not used and you can specify null. For information about this object, see LiveCycle API Reference.

    • A CRLPreferences object that stores certificate revocation list (CRL) preferences. If revocation checking is not done, this parameter is not used and you can specify null.

    • A TSPPreferences object that stores preferences for time stamp provider (TSP) support. This parameter is optional and can be null.

    The sign method returns a BLOB object that represents the signed PDF document.

  5. Save the signed PDF document

    • Create a System.IO.FileStream object by invoking its constructor. Pass a string value that represents the file location of the signed PDF document and the mode in which to open the file.

    • Create a byte array that stores the content of the BLOB object that was returned by the sign method. Populate the byte array by getting the value of the BLOB object’s MTOM data member.

    • Create a System.IO.BinaryWriter object by invoking its constructor and passing the System.IO.FileStream object.

    • Write the contents of the byte array to a PDF file by invoking the System.IO.BinaryWriter object’s Write method and passing the byte array.

// Ethnio survey code removed