Use HSM to digitally sign or certify documents


AEM 6.4 has reached the end of extended support and this documentation is no longer updated. For further details, see our technical support periods. Find the supported versions here.

Hardware security modules (HSM) and etokens are dedicated, hardened, and tamper-resistance computing devices designed to securely manage, process, and store digital keys. These devices are directly attached to a computer or a network server.

Adobe Experience Manager Forms can use credentials stored on an HSM or etoken to eSign or apply server-sided digital signatures to a document. To use an HSM or etoken device with AEM Forms:

  1. Enable the DocAssurance service.
  2. Set up certificates for Reader extension.
  3. Create an alias for the HSM or etoken device in AEM Web Console.
  4. Use the DocAssurance Service APIs to sign or certify the documents with digital keys stored on the device.

Before you configure the HSM or etoken devices with AEM Forms

  • Install AEM Forms add-on package.
  • Install and configure HSM or etoken client software on the same computer as AEM server. The client software is required to communicate with the HSM and etoken devices.
  • (Microsoft Windows only) Set the JAVA_HOME_32 environment variable to point to the directory where the 32-bit version of Java 8 Development Kit (JDK 8) is installed. The default path of the directory is C:\Program Files(x86)\Java\jdk<version>
  • (AEM Forms on OSGi only) Install the root certificate in the trust store. It is required to verify the signed PDF

On Microsoft Windows, only 32-bit LunaSA or EToken clients are supported.

Enable the DocAssurance service

By default, the DocAssurance service is not enabled. Perform the following steps to enable the service:

  1. Stop the Author instance of your AEM Forms environment.

  2. Open the [AEM_root]\crx-quickstart\conf\ file for editing.


    If you have used the [AEM_root]\crx-quickstart\bin\start.bat file to start the AEM instance, then open the [AEM_root]\crx-quickstart\ file for editing.

  3. Add or replace the following properties to the file:

  4. Save and close the file.

  5. Restart the AEM instance.

Set up certificates for Reader extensions

Perform the following steps to setup certificates:

  1. Log in to AEM Author instance as an administrator.

  2. Click Adobe Experience Manager on Global Navigation Bar. Go to Tools > Security > Users.

  3. Click the name field of the user account. The Edit User Settings page opens.

  4. On the AEM Author instance, certificates reside in a KeyStore. If you have not created a KeyStore earlier, click Create KeyStore and set a new password for the KeyStore. If the server already contains a KeyStore, skip this step.

  5. On the Edit User Settings page, click Manage KeyStore.

  6. On KeyStore Management dialog, expand the Add Private Key from Key Store file option and provide an alias. The alias is used to perform the Reader Extensions operation.

  7. To upload the certificate file, click Select Key Store File and upload a .pfx file.

  8. Add the Key Store Password, Private Key Password, and Private Key Alias that is associated with the certificate to the respective fields. Click Submit.


    To determine the Private Key Alias of a certificate, you can use the Java keytool command: keytool -list -v -keystore [keystore-file] -storetype pkcs12


    In the Key Store Password and Private Key Password fields, specify the password provided with the certificate file.


For AEM Forms on OSGi, to verify the signed PDF, the root certificate installed in the Trust Store.


On moving to production environment, replace your evaluation credentials with production credentials. Ensure that you delete your old Reader Extensions credentials, before updating an expired or evaluations credential.

Create an alias for the device

The alias contains all the parameters that an HSM or etoken requires. Perform the instructions listed below to create an alias for each HSM or etoken credential that eSign or Digital Signatures uses :

  1. Open AEM console. The default URL of AEM console is https://<host>:<port>/system/console/configMgr

  2. Open the HSM Credentials Configuration Service and specify values for the following fields:

    • Credential Alias: Specify a string used to identify the alias. This value is used as a property for some Digital Signatures operations, such as the Sign Signature Field operation.
    • DLL Path: Specify the fully qualified path of your HSM or etoken client library on the server. For example, C:\Program Files\LunaSA\cryptoki.dll. In a clustered environment, this path must be identical for all servers in the cluster.
    • HSM Pin: Specify the password required to access the device key.
    • HSM Slot Id: Specify a slot identifier of type integer. The slot ID is set on a client-by-client basis. If you register a second machine to a different partition (for example, HSMPART2 on the same HSM device), then slot 1 is associated with the HSMPART2 partition for the client.

    Note: While configuring Etoken, specify a numeric value for the HSM Slot Id field. A numeric value is required to get the Signatures operations working.

    • Certificate SHA1: Specify SHA1 value (thumbprint) of the public key (.cer) file for the credential you are using. Ensure that there are no spaces used in the SHA1 value. If you are using a physical certificate, then it is not required.
    • HSM Device Type: Select the manufacturer of the HSM (Luna or other) or eToken device.

    Click Save. The hardware security module is configured for AEM Forms. Now, you can use the hardware security module with AEM Forms to sign or certify documents.

Use the DocAssurance Service APIs to sign or certify a document with digital keys stored on the device 

The following sample code uses an HSM or etoken to sign or certify a document.

 * ___________________
 * Copyright 2014 Adobe Systems Incorporated
 * All Rights Reserved.
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
package com.adobe.docassurance.samples;


import javax.jcr.Binary;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;

import com.adobe.aemfd.docmanager.Document;
import com.adobe.fd.docassurance.client.api.DocAssuranceException;
import com.adobe.fd.docassurance.client.api.DocAssuranceService;
import com.adobe.fd.docassurance.client.api.DocAssuranceServiceOperationTypes;
import com.adobe.fd.docassurance.client.api.SignatureOptions;
import com.adobe.fd.signatures.client.types.exceptions.InvalidArgumentException;
import com.adobe.fd.signatures.pdf.inputs.CredentialContext;
import com.adobe.fd.signatures.pdf.inputs.DSSPreferences;
import com.adobe.fd.signatures.pdf.inputs.DSSPreferencesImpl;
import com.adobe.fd.signatures.pdf.inputs.PDFSignatureAppearenceOptions;
import com.adobe.fd.signatures.pdf.inputs.UnlockOptions;
import com.adobe.fd.signatures.pdf.inputs.PDFSignatureAppearenceOptions.PDFSignatureAppearanceType;
import com.adobe.fd.signatures.pdf.inputs.PDFSignatureAppearenceOptions.TextDirection;
import com.adobe.fd.signatures.pki.client.types.common.HashAlgorithm;
import com.adobe.fd.signatures.pki.client.types.common.RevocationCheckStyle;
import com.adobe.fd.signatures.pki.client.types.prefs.CRLPreferences;
import com.adobe.fd.signatures.pki.client.types.prefs.CRLPreferencesImpl;
import com.adobe.fd.signatures.pki.client.types.prefs.GeneralPreferencesImpl;
import com.adobe.fd.signatures.pki.client.types.prefs.PKIPreferences;
import com.adobe.fd.signatures.pki.client.types.prefs.PKIPreferencesImpl;
import com.adobe.fd.signatures.pki.client.types.prefs.PathValidationPreferences;
import com.adobe.fd.signatures.pki.client.types.prefs.PathValidationPreferencesImpl;

 * 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.
 * The following Java code example digitally signs a PDF document that is based on a PDF file.
 * The alias that is specified for the security credential is secure, and revocation checking is performed.
 * Because no CRL or OCSP server information is specified, the server information is obtained from the certificate used to
 * digitally sign the PDF document
 * PreRequisites - Digital certificate for signing the document has to be uploaded on Granite Key Store

public class Sign{
 private DocAssuranceService docAssuranceService;

    private SlingRepository slingRepository;

    private JcrResourceResolverFactory jcrResourceResolverFactory ;

  * @param inputFile - path to the pdf document stored at JCR node
  * @param outputFile - path to the pdf document where the output needs to be stored
  * @throws IOException
  * @throws RepositoryException
  * @throws InvalidArgumentException
  * @throws DocAssuranceException
 public void signExtend(String inputFile, String outputFile, String alias) throws IOException, RepositoryException, InvalidArgumentException, DocAssuranceException{

  Document inDoc = new Document(inputFile);
  Document outDoc = null;

  Session adminSession = null;
        ResourceResolver resourceResolver = null;
        try {

          /** resourceResolver with admin privileges to be passed to SignatureServiceAPI and Reader Extensions
          the resource resolver for signature options has to be corresponding to the user who has the signing certificate in his granite key store
          the resource resolver for signature options has to be corresponding to the user who has the credential for reader extension in his granite key store
          here we are using the same resource resolver
          adminSession = slingRepository.loginAdministrative(null);
             resourceResolver = jcrResourceResolverFactory.getResourceResolver(adminSession);

             //retrieve specifications for each of the services, you may pass null if you don't want to use that service
             //as we don't want encryption in this case, passing null for Encryption Options
             //for encrypted document pass Unlock Options - see the method getUnlockOptions() below
    outDoc = docAssuranceService.secureDocument(inDoc, null, getSignatureOptions(alias,resourceResolver),null,null);
  catch(Exception e){
             * always close the PDFDocument object after your processing is done.
            if(inDoc != null){
            if(adminSession != null && adminSession.isLive()){
                if(resourceResolver != null){

        //flush the output document contents to JCR Node
  flush(outDoc, outputFile);


  * @param rr resource resolver corresponding to the user with the access to signing credential for the
  * given alias "allcertificatesanypolicytest11ee_new" in this case
  * @return SignatureOptions
 private SignatureOptions getSignatureOptions(String alias, ResourceResolver rr){

  //create an instance of SignatureOptions
  SignatureOptions signatureOptions = SignatureOptions.getInstance();

  //set the operation you want to perform - SIGN/CERTIFY

  //field to sign
  String fieldName = "Signature1" ;

        //Hash Algo to be used to compute digest the PDF document
        HashAlgorithm algo = HashAlgorithm.SHA384;

        //Reason for signing/certifying
        String reason = "Test Reason";

        //location of the signer
        String location = "Test Location";

        //contact info of the signer
        String contactInfo = "Test Contact";

        //Create a PDFSignatureAppearanceOptions object
        //and show date information
        PDFSignatureAppearenceOptions appOptions = new PDFSignatureAppearenceOptions(
                PDFSignatureAppearanceType.NAME, null, 1.0d, null, true, true,
                true, true, true, true, true, TextDirection.AUTO);

        signatureOptions.setCredential(new CredentialContext(alias, rr, true));
  return signatureOptions;

 private DSSPreferences getDSSPreferences(ResourceResolver rr){
  //sets the DSS Preferences
        DSSPreferencesImpl prefs = DSSPreferencesImpl.getInstance();
        GeneralPreferencesImpl gp = (GeneralPreferencesImpl) prefs.getPKIPreferences().getGeneralPreferences();
        return prefs;

    private PKIPreferences getPKIPreferences(){
     //sets the PKI Preferences
        PKIPreferences pkiPref = new PKIPreferencesImpl();
        return pkiPref;

    private CRLPreferences getCRLPreferences(){
        //specifies the CRL Preferences
        CRLPreferencesImpl crlPrefs = new CRLPreferencesImpl();
        return crlPrefs;

    private PathValidationPreferences getPathValidationPreferences(){
     //sets the path validation preferences
        PathValidationPreferencesImpl pathPref = new PathValidationPreferencesImpl();
        return pathPref;


     * sets Unlock Options for encrypted PDF
    private UnlockOptions getUnlockOptions(){
        UnlockOptions unlockOptions = new UnlockOptions();
        //sets the Open Password for password encrypted PDF

        //for Certificate Encrypted Document, set the alias of the credential uploaded in the user's key store
        //and corresponding resource resolver

        return unlockOptions;

     * This method copies the data from {@code Document}, to the specified file at the given resourcePath.
     * @param doc
     * @param resourcePath
     * @throws IOException
    private void flush(Document doc, String resourcePath) throws IOException {
   //extracts the byte data from Document
   byte[] output = doc.getInlineData();
   Binary opBin;
   Session adminSession = null;
      try {
         adminSession = slingRepository.loginAdministrative(null);

         //get access to the specific node
         //here we are assuming that node exists
           Node node = adminSession.getNode(resourcePath);

           //convert byte[] to Binary
           opBin = adminSession.getValueFactory().createBinary((InputStream)new ByteArrayInputStream(output));

           //set the Binary data value to node's jcr:data
      } catch (RepositoryException e) {


       if(adminSession != null && adminSession.isLive()){
        try {;
     } catch (RepositoryException e) {




If you have upgraded from AEM 6.0 Form or AEM 6.1 Forms, and you were using the DocAssurance service in the previous version, then:

  • To use the DocAssurance service without an HSM or etoken device, keep using the existing code.
  • To use the DocAssurance service with an HSM or etoken device, replace your existing CredentialContext object code with the API listed below.
  * @param credentialAlias alias of the PKI Credential stored in CQ Key Store or
  * the alias of the HSM Credential configured using HSM Credentials Configuration Service.
  * @param resourceResolver corresponding to the user with the access to the key store and trust store.
  * @param isHSMCredential if the alias is corresponding to HSM Credential.
 public CredentialContext(String credentialAlias, ResourceResolver resourceResolver, boolean isHSMCredential);

For detailed information about APIs and sample code of the DocAssurance service, see Using AEM Document Services Programmatically.

On this page