Show Menu
TEMAS×

Utilice HSM para firmar o certificar documentos digitalmente

Los módulos de seguridad de hardware (HSM) y las cookies son dispositivos informáticos dedicados, reforzados y resistentes a las manipulaciones diseñados para administrar, procesar y almacenar claves digitales de forma segura. Estos dispositivos están conectados directamente a un equipo o a un servidor de red.
Los formularios de Adobe Experience Manager pueden utilizar las credenciales almacenadas en un HSM o grabadas para firmar electrónicamente o aplicar firmas digitales de servidor a un documento. Para utilizar un HSM o un dispositivo de activación con AEM Forms:
  1. Habilite el servicio DocAssurance.
  2. Configure los certificados para la extensión Reader.
  3. Cree un alias para el HSM o dispositivo de activación en la consola web de AEM.
  4. Utilice las API del servicio DocAssurance para firmar o certificar los documentos con claves digitales almacenadas en el dispositivo.

Antes de configurar los dispositivos HSM o de activación con AEM Forms

  • Install AEM Forms add-on package.
  • Instale y configure el software de cliente HSM o Token en el mismo equipo que el servidor AEM. El software cliente es necesario para comunicarse con el HSM y los dispositivos de activación.
  • (Solo Microsoft Windows) Configure la variable de entorno JAVA_HOME_32 para que señale al directorio en el que está instalada la versión de 32 bits de Java 8 Development Kit (JDK 8). La ruta predeterminada del directorio es C:\Program Files(x86)\Java\jdk<version>
  • (Solo AEM Forms en OSGi) Instale el certificado raíz en el almacén de confianza. Es necesario verificar el PDF firmado
En Microsoft Windows, solo se admiten clientes LunaSA o EToken de 32 bits.

Habilitar el servicio DocAssurance

De forma predeterminada, el servicio DocAssurance no está habilitado. Realice los siguientes pasos para habilitar el servicio:
  1. Detenga la instancia de autor del entorno de AEM Forms.
  2. Abra el archivo #\crx-quickstart\conf\sling.properties para editarlo.
    Si ha utilizado el archivo #\crx-quickstart\bin\start.bat para iniciar la instancia de AEM, abra el archivo #\crx-quickstart\sling.properties para editarlo.
  3. Agregue o reemplace las siguientes propiedades en el archivo sling.properties:
    sling.bootdelegation.sun=sun.*,com.sun.*,sun.misc.*
    sling.bootdelegation.ibm=com.ibm.xml.*,com.ibm.*
    sling.bootdelegation.class.com.rsa.jsafe.provider.JsafeJCE=com.rsa.*
    sling.bootdelegation.class.org.bouncycastle.jce.provider.BouncyCastleProvider=org.bouncycastle.*
    
    
  4. Guarde y cierre el archivo sling.properties.
  5. Reinicie la instancia de AEM.

Configuración de certificados para extensiones de Reader

Realice los siguientes pasos para configurar los certificados:
  1. Inicie sesión en la instancia de AEM Author como administrador.
  2. Haga clic en Adobe Experience Manager en la barra de navegación global. Vaya a Herramientas > Seguridad > Usuarios .
  3. Haga clic en el campo nombre de la cuenta de usuario. Se abre la página Editar configuración de usuario.
  4. En la instancia de AEM Author, los certificados residen en un KeyStore. Si no ha creado un KeyStore anteriormente, haga clic en Crear KeyStore y defina una nueva contraseña para el KeyStore. Si el servidor ya contiene un KeyStore, omita este paso.
  5. En la página Editar configuración de usuario, haga clic en Administrar almacén de claves .
  6. En el cuadro de diálogo Administración de KeyStore, expanda la opción Agregar clave privada del archivo Almacén de claves y proporcione un alias. El alias se utiliza para realizar la operación Reader Extensions.
  7. Para cargar el archivo de certificado, haga clic en Seleccionar archivo de almacén de claves y cargue un .pfx archivo.
  8. Agregue la contraseña del almacén de claves, la contraseña de clave privada y el alias de clave privada asociados al certificado a los campos correspondientes. Haga clic en Enviar .
    Para determinar el alias de clave privada de un certificado, puede utilizar el comando de la herramienta de clave de Java: keytool -list -v -keystore [keystore-file] -storetype pkcs12
    En los campos Contraseña del almacén de claves y Contraseña de clave privada, especifique la contraseña proporcionada con el archivo de certificado.
Para los formularios AEM en OSGi, para comprobar el PDF firmado, el certificado raíz instalado en el almacén de confianza.
Al pasar al entorno de producción, reemplace sus credenciales de evaluación por credenciales de producción. Asegúrese de eliminar las credenciales antiguas de Reader Extensions antes de actualizar una credencial de evaluación o caducada.

Creación de un alias para el dispositivo

El alias contiene todos los parámetros que requiere un HSM o una cookie. Siga las instrucciones que se indican a continuación para crear un alias para cada credencial de HSM o de activación que utilice eSign o Digital Signatures:
  1. Abra la consola de AEM. La dirección URL predeterminada de la consola de AEM es https://<host>:<puerto>/system/console/configMgr
  2. Abra el servicio de configuración de credenciales de HSM y especifique los valores de los campos siguientes:
    • Alias de credencial: Especifique una cadena utilizada para identificar el alias. Este valor se utiliza como propiedad para algunas operaciones de firmas digitales, como la operación Firmar campo de firma.
    • Ruta de DLL: Especifique la ruta completa de su HSM o biblioteca de cliente activada en el servidor. Por ejemplo, C:\Program Files\LunaSA\cryptoki.dll. En un entorno agrupado, esta ruta debe ser idéntica para todos los servidores del clúster.
    • Pin HSM: Especifique la contraseña necesaria para acceder a la clave del dispositivo.
    • Id de ranura HSM: Especifique un identificador de ranura de tipo entero. El ID de ranura se establece cliente por cliente. Si registra una segunda máquina en una partición diferente (por ejemplo, HSMPART2 en el mismo dispositivo HSM), entonces la ranura 1 se asocia con la partición HSMPART2 para el cliente. ​Nota: Durante la configuración de Etoken, especifique un valor numérico para el campo Id. de ranura HSM. Se requiere un valor numérico para que funcionen las operaciones Firmas.
    • Certificado SHA1 : Especifique el valor SHA1 (huella digital) del archivo de clave pública (.cer) para las credenciales que está utilizando. Asegúrese de que no hay espacios utilizados en el valor SHA1. Si utiliza un certificado físico, no es obligatorio.
    • Tipo de dispositivo HSM: Seleccione el fabricante del HSM (Luna u otro) o dispositivo eToken. Haga clic en Guardar. El módulo de seguridad de hardware está configurado para AEM Forms. Ahora puede utilizar el módulo de seguridad de hardware con AEM Forms para firmar o certificar documentos.

Utilice las API del servicio DocAssurance para firmar o certificar un documento con claves digitales almacenadas en el dispositivo

El siguiente código de muestra utiliza un HSM o un token para firmar o certificar un documento.
/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * ___________________
 *
 * 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 java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

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 org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.resource.JcrResourceResolverFactory;

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
 */

@Component
@Service(value=Sign.class)
public class Sign{
 @Reference
 private DocAssuranceService docAssuranceService;
 
 @Reference
    private SlingRepository slingRepository;
 
 @Reference
    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){
   e.printStackTrace();
  }
        finally{
            /**
             * always close the PDFDocument object after your processing is done.
             */
            if(inDoc != null){
                inDoc.close();
            }
            if(adminSession != null && adminSession.isLive()){
                if(resourceResolver != null){
                    resourceResolver.close();
                }
                adminSession.logout();
            }
        }
        
        //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
  signatureOptions.setOperationType(DocAssuranceServiceOperationTypes.SIGN);
  
  //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.setSignatureFieldName(fieldName);
        signatureOptions.setAlgo(algo);
        signatureOptions.setContactInfo(contactInfo);
        signatureOptions.setLocation(location);
        signatureOptions.setSigAppearence(appOptions);
        signatureOptions.setReason(reason);
        signatureOptions.setDssPref(getDSSPreferences(rr));
        signatureOptions.setCredential(new CredentialContext(alias, rr, true));
  return signatureOptions;
 }
 
 private DSSPreferences getDSSPreferences(ResourceResolver rr){
  //sets the DSS Preferences
        DSSPreferencesImpl prefs = DSSPreferencesImpl.getInstance();
        prefs.setPKIPreferences(getPKIPreferences());
        GeneralPreferencesImpl gp = (GeneralPreferencesImpl) prefs.getPKIPreferences().getGeneralPreferences();
        gp.setDisableCache(true);
        return prefs;
    }
    
    private PKIPreferences getPKIPreferences(){
     //sets the PKI Preferences
        PKIPreferences pkiPref = new PKIPreferencesImpl();
        pkiPref.setCRLPreferences(getCRLPreferences());
        pkiPref.setPathPreferences(getPathValidationPreferences());
        return pkiPref;
    }
    
    private CRLPreferences getCRLPreferences(){
        //specifies the CRL Preferences
        CRLPreferencesImpl crlPrefs = new CRLPreferencesImpl();
        crlPrefs.setRevocationCheck(RevocationCheckStyle.CheckIfAvailable);
        crlPrefs.setGoOnline(true);
        return crlPrefs;
    }
    
    private PathValidationPreferences getPathValidationPreferences(){
     //sets the path validation preferences
        PathValidationPreferencesImpl pathPref = new PathValidationPreferencesImpl();
        pathPref.setDoValidation(false);
        return pathPref;
        
    }
    
    /**
     * sets Unlock Options for encrypted PDF
     */
    private UnlockOptions getUnlockOptions(){
        UnlockOptions unlockOptions = new UnlockOptions();
        //sets the Open Password for password encrypted PDF
        unlockOptions.setPassword("OpenPassword");
        
        //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
           node.getNode("jcr:content").getProperty("jcr:data").setValue(opBin);
      } catch (RepositoryException e) {

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

Si ha actualizado desde AEM 6.0 Form o AEM 6.1 Forms y estaba utilizando el servicio DocAssurance en la versión anterior, haga lo siguiente:
  • Para utilizar el servicio DocAssurance sin un HSM o dispositivo de activación, siga utilizando el código existente.
  • Para utilizar el servicio DocAssurance con un HSM o dispositivo de activación, sustituya el código de objeto CredentialContext existente por la API que se indica a continuación.
/**
  * 
  * @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);

Para obtener información detallada sobre las API y el código de muestra del servicio DocAssurance, consulte Uso de AEM Document Services mediante programación .