

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Utilice Client SDK 3 para integrarse AWS CloudHSM con Java Keytool y Jarsigner
<a name="keystore-third-party-tools"></a>

AWS CloudHSM el almacén de claves es un almacén de claves JCE de uso especial que utiliza los certificados asociados a las claves del módulo de seguridad de hardware (HSM) mediante herramientas de terceros, como y. `keytool` `jarsigner` AWS CloudHSM no almacena los certificados en el HSM, ya que los certificados son datos públicos y no confidenciales. El almacén de AWS CloudHSM claves almacena los certificados en un archivo local y los asigna a las claves correspondientes del HSM. 

Cuando utiliza el almacén de AWS CloudHSM claves para generar nuevas claves, no se genera ninguna entrada en el archivo del almacén de claves local; las claves se crean en el HSM. Del mismo modo, cuando utiliza el almacén de claves de AWS CloudHSM para buscar claves, la búsqueda se transfiere al HSM. Al almacenar los certificados en el almacén de AWS CloudHSM claves, el proveedor comprueba que existe un par de claves con el alias correspondiente en el HSM y, a continuación, asocia el certificado proporcionado al par de claves correspondiente. 

**Topics**
+ [Requisitos previos](keystore-prerequisites.md)
+ [Usar el almacén de claves con Keytool](using_keystore_with_keytool.md)
+ [Usar el almacén de claves con Jarsigner](using_keystore_jarsigner.md)
+ [Problemas conocidos](known-issues-keytool-jarsigner.md)
+ [Registrar claves preexistentes con el almacén de claves](register-pre-existing-keys-with-keystore.md)

# Requisitos previos para la integración AWS CloudHSM con Java Keytool y Jarsigner mediante Client SDK 3
<a name="keystore-prerequisites"></a>

Para usar el almacén de AWS CloudHSM claves, primero debe inicializar y configurar el SDK de JCE. AWS CloudHSM Para ello, siga los siguientes pasos. 

## Paso 1: Instalar JCE
<a name="prereq-step-one"></a>

Para instalar el JCE, incluidos los requisitos previos del AWS CloudHSM cliente, siga los pasos para [instalar](java-library-install.md) la biblioteca Java. 

## Paso 2: Agregar credenciales de inicio de sesión de HSM a variables de entorno
<a name="prereq-step-two"></a>

Configure las variables de entorno para que contengan las credenciales de inicio de sesión de HSM. 

```
export HSM_PARTITION=PARTITION_1
export HSM_USER=<HSM user name> 
export HSM_PASSWORD=<HSM password>
```

**nota**  
La JCE de CloudHSM dispone de varias opciones de inicio de sesión. Para utilizar el almacén de AWS CloudHSM claves con aplicaciones de terceros, debe utilizar el inicio de sesión implícito con variables de entorno. Si desea utilizar el inicio de sesión explícito a través del código de la aplicación, debe crear su propia aplicación con el almacén de AWS CloudHSM claves. Para obtener información adicional, consulte el artículo sobre el [uso del almacén de AWS CloudHSM claves](alternative-keystore.md). 

## Paso 3: Registrar el proveedor de JCE
<a name="prereq-step-three"></a>

Para registrar el proveedor de JCE, en la CloudProvider configuración de Java. 

1. Abra el archivo de configuración java.security de la instalación de Java para editarlo.

1. En el archivo de configuración java.security, agregue `com.cavium.provider.CaviumProvider` como último proveedor. Por ejemplo, si hay nueve proveedores en el archivo java.security, agregue el siguiente proveedor como último proveedor de la sección. Si el proveedor de Cavium se agregara con una prioridad mayor, el rendimiento del sistema podría verse negativamente afectado.

   `security.provider.10=com.cavium.provider.CaviumProvider`
**nota**  
Es posible que los usuarios avanzados estén acostumbrados a especificar las opciones `-providerName`, `-providerclass` y `-providerpath` de la línea de comandos cuando utilizan keytool, en lugar de actualizar el archivo de configuración de seguridad. Si intenta especificar las opciones de la línea de comandos al generar claves con el almacén de AWS CloudHSM claves, se producirán errores. 

# Utilice el almacén de AWS CloudHSM claves con keytool mediante Client SDK 3
<a name="using_keystore_with_keytool"></a>

[ Keytool](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html) es una conocida utilidad de línea de comandos para tareas comunes de claves y certificados en los sistemas Linux. La documentación de AWS CloudHSM no ofrece un tutorial completo sobre keytool. En este artículo se explican los parámetros específicos que se deben utilizar con las distintas funciones de las herramientas clave cuando se utilizan AWS CloudHSM como fuente de confianza a través del almacén de AWS CloudHSM claves.

Cuando utilice keytool con el almacén de AWS CloudHSM claves, especifique los siguientes argumentos para cualquier comando de keytool:

```
-storetype CLOUDHSM \
		-J-classpath '-J/opt/cloudhsm/java/*' \
		-J-Djava.library.path=/opt/cloudhsm/lib
```

Si desea crear un nuevo archivo de almacén de claves mediante el almacén de AWS CloudHSM claves, consulte. [Utilice el SDK 3 para el cliente AWS CloudHSM KeyStore AWS CloudHSM](alternative-keystore.md#using_cloudhsm_keystore) Si desea utilizar un almacén de claves existente, especifique el nombre (incluida la ruta) con el argumento keystore en keytool. Si especifica un archivo de almacén de claves que no existe en un comando de keytool, el almacén de AWS CloudHSM claves crea un nuevo archivo de almacén de claves.

# Cree nuevas AWS CloudHSM claves con la herramienta de teclas
<a name="create_key_keytool"></a>

Puede utilizar keytool para generar cualquier tipo de clave compatible con el SDK de AWS CloudHSM JCE. Vea la lista completa de claves junto con su longitud en el artículo de [claves admitidas](java-lib-supported.md#java-keys) de la biblioteca de Java.

**importante**  
Una clave generada a través de keytool se genera en el software y, a continuación, se importa AWS CloudHSM como una clave persistente y extraíble.

[Las instrucciones para crear claves no extraíbles directamente en el módulo de seguridad de hardware (HSM) y luego usarlas con keytool o Jarsigner se muestran en el ejemplo de código de Registrar claves preexistentes con Key Store. AWS CloudHSM](register-pre-existing-keys-with-keystore.md) Le recomendamos encarecidamente que genere las claves no exportables fuera de keytool y que después importe los certificados correspondientes en el almacén de claves. Si utiliza claves RSA o EC extraíbles a través de keytool y jarsigner, los proveedores exportan las claves y, a continuación, las utilizan localmente para las operaciones de firma. AWS CloudHSM 

Si tiene varias instancias de cliente conectadas al clúster de CloudHSM, tenga en cuenta que, aunque se importe un certificado en el almacén de claves de una instancia del cliente, los certificados no estarán disponibles automáticamente en otras instancias del cliente. Para registrar la clave y los certificados asociados en cada instancia del cliente, debe ejecutar una aplicación Java, tal y como se describe en [Generar una CSR con Keytool](generate_csr_using_keytool.md). Si lo desea, también puede realizar los cambios necesarios en un cliente y copiar el archivo de almacén de claves resultante en las demás instancias del cliente.

**Ejemplo 1: **generar una clave simétrica AES-256 y guardarla en un archivo de almacén de claves denominado “example\$1keystore.store” en el directorio de trabajo. Sustitúyala por *<secret label>* una etiqueta única.

```
keytool -genseckey -alias <secret label> -keyalg aes \
		-keysize 256 -keystore example_keystore.store \
		-storetype CloudHSM -J-classpath '-J/opt/cloudhsm/java/*' \
		-J-Djava.library.path=/opt/cloudhsm/lib/
```

**Ejemplo 2: **generar un par de claves RSA-2048 y guardarlo en un archivo de almacén de claves denominado “example\$1keystore.store” en el directorio de trabajo. *<RSA key pair label>*Sustitúyala por una etiqueta única.

```
keytool -genkeypair -alias <RSA key pair label> \
        -keyalg rsa -keysize 2048 \
        -sigalg sha512withrsa \
        -keystore example_keystore.store \
        -storetype CLOUDHSM \
        -J-classpath '-J/opt/cloudhsm/java/*' \
        -J-Djava.library.path=/opt/cloudhsm/lib/
```

**Ejemplo 3: **generar una clave ED p256 y guardarla en un archivo de almacén de claves denominado “example\$1keystore.store” en el directorio de trabajo. *<ec key pair label>*Sustitúyala por una etiqueta única.

```
keytool -genkeypair -alias <ec key pair label> \
        -keyalg ec -keysize 256 \
        -sigalg SHA512withECDSA \
        -keystore example_keystore.store \
        -storetype CLOUDHSM \
        -J-classpath '-J/opt/cloudhsm/java/*' \
        -J-Djava.library.path=/opt/cloudhsm/lib/
```

Encontrará una lista de los [algoritmos de firma compatibles](java-lib-supported.md#java-sign-verify) en la biblioteca de Java.

# Elimine una AWS CloudHSM clave con keytool
<a name="delete_key_using_keytool"></a>

El almacén de AWS CloudHSM claves no admite la eliminación de claves. Para eliminar la clave, debe usar la `deleteKey` función de la herramienta AWS CloudHSM de línea de comandos,[Eliminar una AWS CloudHSM clave mediante KMU](key_mgmt_util-deleteKey.md).

# Genere una AWS CloudHSM CSR con keytool
<a name="generate_csr_using_keytool"></a>

Para tener la máxima flexibilidad al generar una solicitud de firma de certificado (CSR), utilice [Motor AWS CloudHSM dinámico OpenSSL para Client SDK 5](openssl-library.md). El comando siguiente utiliza keytool para generar una CSR de un par de claves con el alias `example-key-pair`.

```
keytool -certreq -alias <key pair label> \
        -file example_csr.csr \
        -keystore example_keystore.store \
        -storetype CLOUDHSM \
        -J-classpath '-J/opt/cloudhsm/java/*' \
        -J-Djava.library.path=/opt/cloudhsm/lib/
```

**nota**  
Para poder utilizar un par de claves de keytool, ese par de claves debe tener una entrada en el archivo de almacén de claves especificado. Si desea utilizar un par de claves generado fuera de keytool, debe importar los metadatos de las claves y los certificados en el almacén de claves. Para obtener instrucciones sobre cómo importar los datos del almacén de claves, consulte [Importación de certificados intermedios y raíz al almacén de AWS CloudHSM claves mediante](import_cert_using_keytool.md) Keytool.

# Utilice la herramienta clave para importar certificados intermedios y raíz al almacén de claves AWS CloudHSM
<a name="import_cert_using_keytool"></a>

Para importar un certificado de CA AWS CloudHSM, debe habilitar la verificación de una cadena de certificados completa en un certificado recién importado. A continuación, se muestra un ejemplo del comando: 

```
keytool -import -trustcacerts -alias rootCAcert \
        -file rootCAcert.cert -keystore example_keystore.store \
        -storetype CLOUDHSM \
        -J-classpath '-J/opt/cloudhsm/java/*' \
        -J-Djava.library.path=/opt/cloudhsm/lib/
```

Si conecta varias instancias de cliente a su AWS CloudHSM clúster, la importación de un certificado al almacén de claves de una instancia de cliente no hará que el certificado esté disponible automáticamente en otras instancias de cliente. Es necesario importar el certificado en cada instancia del cliente.

# Usa keytool para eliminar los certificados del almacén de AWS CloudHSM claves
<a name="delete_cert_using_keytool"></a>

El siguiente comando muestra un ejemplo de cómo eliminar un AWS CloudHSM certificado de un almacén de claves keytool de Java. 

```
keytool -delete -alias mydomain -keystore \
        -keystore example_keystore.store \
        -storetype CLOUDHSM \
        -J-classpath '-J/opt/cloudhsm/java/*' \
        -J-Djava.library.path=/opt/cloudhsm/lib/
```

Si conectas varias instancias de cliente a tu AWS CloudHSM clúster, eliminar un certificado del almacén de claves de una instancia de cliente no eliminará automáticamente el certificado de otras instancias de cliente. Es necesario eliminar el certificado en cada instancia de cliente.

# Importa un certificado que funcione al almacén de AWS CloudHSM claves mediante keytool
<a name="import_working_cert_using_keytool"></a>

Cuando se firma una solicitud de firma de certificado (CSR), es posible importarla en el almacén de claves de AWS CloudHSM y asociarla con el par de claves apropiado. Puede ver un ejemplo en el siguiente comando: 

```
keytool -importcert -noprompt -alias <key pair label> \
        -file example_certificate.crt \
        -keystore example_keystore.store
        -storetype CLOUDHSM \
        -J-classpath '-J/opt/cloudhsm/java/*' \
        -J-Djava.library.path=/opt/cloudhsm/lib/
```

El alias debe ser un par de claves con un certificado asociado del almacén de claves. Si la clave se genera fuera de keytool o en otra instancia del cliente, primero debe importar los metadatos de la clave y el certificado en el almacén de claves. Para obtener instrucciones sobre cómo importar los metadatos del certificado, consulte el ejemplo de código en Cómo [registrar claves preexistentes en el almacén de AWS CloudHSM claves](register-pre-existing-keys-with-keystore.md). 

Es necesario que la cadena de certificados se pueda verificar. Si no puede verificar el certificado, es posible que deba importar el certificado de firma (entidad de certificación) en el almacén de claves para poder verificar la cadena.

# Exporte un certificado AWS CloudHSM mediante keytool
<a name="export_cert_using_keytool"></a>

En el ejemplo siguiente, se genera un certificado en formato X.509 binario. Para exportar un certificado legible por humanos AWS CloudHSM, añada `-rfc` al `-exportcert` comando. 

```
keytool -exportcert -alias <key pair label> \
        -file example_exported_certificate.crt \
        -keystore example_keystore.store \
        -storetype CLOUDHSM \
        -J-classpath '-J/opt/cloudhsm/java/*' \
        -J-Djava.library.path=/opt/cloudhsm/lib/
```

# Utilice el almacén de AWS CloudHSM claves con Jarsigner mediante Client SDK 3
<a name="using_keystore_jarsigner"></a>

Jarsigner es una conocida utilidad de línea de comandos que permite firmar archivos JAR con una clave almacenada de forma segura en un módulo de seguridad de hardware (HSM). La documentación no incluye un tutorial completo sobre Jarsigner. AWS CloudHSM En esta sección, se explican los parámetros de Jarsigner que debe utilizar para firmar y verificar las firmas AWS CloudHSM como fuente de confianza a través del almacén de claves. AWS CloudHSM 

# Configura AWS CloudHSM claves y certificados con Jarsigner
<a name="jarsigner_set_up_certificates"></a>

Antes de poder firmar archivos AWS CloudHSM JAR con Jarsigner, asegúrese de haber configurado o completado los siguientes pasos: 

1. Siga las instrucciones de los [requisitos previos del almacén de claves de AWS CloudHSM](keystore-prerequisites.md).

1. Configure las claves de firma y los certificados y la cadena de certificados asociados, que deben almacenarse en el almacén de AWS CloudHSM claves de la instancia de servidor o cliente actual. Cree las claves AWS CloudHSM y, a continuación, importe los metadatos asociados a su almacén de AWS CloudHSM claves. Utilice el ejemplo de código de [Registrar claves preexistentes en el almacén de AWS CloudHSM claves](register-pre-existing-keys-with-keystore.md) para importar los metadatos al almacén de claves. Si desea utilizar keytool para configurar las claves y los certificados, consulte [Cree nuevas AWS CloudHSM claves con la herramienta de teclas](create_key_keytool.md). Si utiliza varias instancias de cliente para firmar la suya JARs, cree la clave e importe la cadena de certificados. A continuación, copie el archivo de almacén de claves resultante en cada instancia del cliente. Si genera nuevas claves con frecuencia, es posible que le resulte más fácil importar los certificados individualmente en cada instancia del cliente.

1. Toda la cadena de certificados debe ser verificable. Para que la cadena de certificados sea verificable, es posible que deba agregar el certificado de CA y los certificados intermedios al almacén de AWS CloudHSM claves. Consulte el fragmento de código en [Firmar un archivo JAR con Jarsigner para obtener instrucciones sobre cómo usar AWS CloudHSM](jarsigner_sign_jar_using_hsm_jarsigner.md) el código Java para verificar la cadena de certificados. Si lo prefiere, puede utilizar keytool para importar los certificados. Para obtener instrucciones sobre el uso de keytool, consulte [Uso de Keytool para importar certificados intermedios y raíz a](import_cert_using_keytool.md) Key Store. AWS CloudHSM 

# Firme un archivo JAR con Jarsigner AWS CloudHSM
<a name="jarsigner_sign_jar_using_hsm_jarsigner"></a>

Utilice el siguiente comando para firmar un archivo JAR con AWS CloudHSM un jarsigner: 

```
jarsigner -keystore example_keystore.store \
        -signedjar signthisclass_signed.jar \
        -sigalg sha512withrsa \
        -storetype CloudHSM \
        -J-classpath '-J/opt/cloudhsm/java/*:/usr/lib/jvm/java-1.8.0/lib/tools.jar' \
        -J-Djava.library.path=/opt/cloudhsm/lib \
        signthisclass.jar <key pair label>
```

Utilice el siguiente comando para verificar un JAR firmado: 

```
jarsigner -verify \
        -keystore example_keystore.store \
        -sigalg sha512withrsa \
        -storetype CloudHSM \
        -J-classpath '-J/opt/cloudhsm/java/*:/usr/lib/jvm/java-1.8.0/lib/tools.jar' \
        -J-Djava.library.path=/opt/cloudhsm/lib \
        signthisclass_signed.jar <key pair label>
```

# Problemas conocidos relacionados con la AWS CloudHSM integración de Java Keytool y Jarsigner mediante Client SDK 3
<a name="known-issues-keytool-jarsigner"></a>

La siguiente lista proporciona la lista actual de problemas conocidos relacionados con las integraciones con Java Keytool AWS CloudHSM y Jarsigner mediante Client SDK 3. 
+ Al generar claves mediante keytool, el primer proveedor de la configuración del proveedor no puede ser. CaviumProvider 
+ Cuando se generan claves con keytool, el primer proveedor (compatible) del archivo de configuración de seguridad se utiliza para generar la clave. Normalmente, es un proveedor de software. A continuación, se asigna un alias a la clave generada y se importa al AWS CloudHSM HSM como clave persistente (simbólica) durante el proceso de adición de claves. 
+  Cuando utilices keytool con un almacén de AWS CloudHSM claves, no especifiques `-providerName` ni `-providerpath` opciones en la línea de comandos. `-providerclass` Especifique estas opciones en el archivo del proveedor de seguridad tal y como se describe en los [requisitos previos del almacén de claves](keystore-prerequisites.md). 
+ Cuando se utilizan claves EC no extraíbles a través de keytool y Jarsigner, el proveedor de SunEC debe removed/disabled ser de la lista de proveedores del archivo java.security. Si utilizas claves EC extraíbles a través de keytool y Jarsigner, los proveedores exportan los bits clave del HSM y utilizan la clave localmente para las operaciones de firma. AWS CloudHSM No se recomienda utilizar claves exportables con keytool o Jarsigner.

# Registre las claves preexistentes en el almacén de claves AWS CloudHSM
<a name="register-pre-existing-keys-with-keystore"></a>

Para obtener la máxima seguridad y flexibilidad en cuanto a los atributos y el etiquetado, te recomendamos que generes tus claves de AWS CloudHSM firma con [key\$1mgmt\$1util](generate-keys.md). También puede usar una aplicación de Java para generar la clave en AWS CloudHSM.

En la siguiente sección se proporciona un ejemplo de código que muestra cómo generar un nuevo par de claves en el HSM y registrarlo con las claves existentes importadas al almacén de AWS CloudHSM claves. Las claves importadas están disponibles para que puedan utilizarse en herramientas de terceros como keytool y Jarsigner. 

Si desea utilizar una clave preexistente, modifique el ejemplo de código para buscar una clave por su etiqueta en lugar de generar una clave nueva. El ejemplo de código para buscar una clave por etiqueta está disponible en el [ejemplo KeyUtilitiesRunner .java de](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/master/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java). GitHub 

**importante**  
Al registrar una clave almacenada en AWS CloudHSM un almacén de claves local, no se exporta la clave. Cuando se registra la clave, el almacén de claves registra el alias (o la etiqueta) de la clave y relaciona localmente los objetos del certificado del almacén con un par de claves de AWS CloudHSM. Si el par de claves se crea como no exportable, los bits de la clave no saldrán del HSM. 

```
                      	
                      	
                      	//
 // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
 // software and associated documentation files (the "Software"), to deal in the Software
 // without restriction, including without limitation the rights to use, copy, modify,
 // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 // permit persons to whom the Software is furnished to do so.
 //
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
package com.amazonaws.cloudhsm.examples;

import com.cavium.key.CaviumKey;
import com.cavium.key.parameter.CaviumAESKeyGenParameterSpec;
import com.cavium.key.parameter.CaviumRSAKeyGenParameterSpec;
import com.cavium.asn1.Encoder;
import com.cavium.cfm2.Util;

import javax.crypto.KeyGenerator;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;

import java.math.BigInteger;

import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.KeyStore.PasswordProtection;
import java.security.KeyStore.PrivateKeyEntry;
import java.security.KeyStore.Entry;

import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;

//
// KeyStoreExampleRunner demonstrates how to load a keystore, and associate a certificate with a
// key in that keystore.
//
// This example relies on implicit credentials, so you must setup your environment correctly.
//
// https://docs.aws.amazon.com/cloudhsm/latest/userguide/java-library-install.html#java-library-credentials
//

public class KeyStoreExampleRunner {

     private static byte[] COMMON_NAME_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x03 };
     private static byte[] COUNTRY_NAME_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x06 };
     private static byte[] LOCALITY_NAME_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x07 };
     private static byte[] STATE_OR_PROVINCE_NAME_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x08 };
     private static byte[] ORGANIZATION_NAME_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x0A };
     private static byte[] ORGANIZATION_UNIT_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x0B };

     private static String helpString = "KeyStoreExampleRunner%n" +
            "This sample demonstrates how to load and store keys using a keystore.%n%n" +
            "Options%n" +
            "\t--help\t\t\tDisplay this message.%n" +
            "\t--store <filename>\t\tPath of the keystore.%n" +
            "\t--password <password>\t\tPassword for the keystore (not your CU password).%n" +
            "\t--label <label>\t\t\tLabel to store the key and certificate under.%n" +
            "\t--list\t\t\tList all the keys in the keystore.%n%n";

    public static void main(String[] args) throws Exception {
        Security.addProvider(new com.cavium.provider.CaviumProvider());
        KeyStore keyStore = KeyStore.getInstance("CloudHSM");

        String keystoreFile = null;
        String password = null;
        String label = null;
        boolean list = false;
        for (int i = 0; i < args.length; i++) {
            String arg = args[i];
            switch (args[i]) {
                case "--store":
                    keystoreFile = args[++i];
                    break;
                case "--password":
                    password = args[++i];
                    break;
                case "--label":
                    label = args[++i];
                    break;
                case "--list":
                    list = true;
                    break;
                case "--help":
                    help();
                    return;
            }
        }

        if (null == keystoreFile || null == password) {
            help();
            return;
        }

        if (list) {
            listKeys(keystoreFile, password);
            return;
        }

        if (null == label) {
            label = "Keystore Example Keypair";
        }

        //
        // This call to keyStore.load() will open the pkcs12 keystore with the supplied
        // password and connect to the HSM. The CU credentials must be specified using
        // standard CloudHSM login methods.
        //
        try {
            FileInputStream instream = new FileInputStream(keystoreFile);
            keyStore.load(instream, password.toCharArray());
        } catch (FileNotFoundException ex) {
            System.err.println("Keystore not found, loading an empty store");
            keyStore.load(null, null);
        }

        PasswordProtection passwd = new PasswordProtection(password.toCharArray());
        System.out.println("Searching for example key and certificate...");

        PrivateKeyEntry keyEntry = (PrivateKeyEntry) keyStore.getEntry(label, passwd);
        if (null == keyEntry) {
            //
            // No entry was found, so we need to create a key pair and associate a certificate.
            // The private key will get the label passed on the command line. The keystore alias
            // needs to be the same as the private key label. The public key will have ":public"
            // appended to it. The alias used in the keystore will We associate the certificate
            // with the private key.
            //
            System.out.println("No entry found, creating...");
            KeyPair kp = generateRSAKeyPair(2048, label + ":public", label);
            System.out.printf("Created a key pair with the handles %d/%d%n", ((CaviumKey) kp.getPrivate()).getHandle(), ((CaviumKey) kp.getPublic()).getHandle());

            //
            // Generate a certificate and associate the chain with the private key.
            //
            Certificate self_signed_cert = generateCert(kp);
            Certificate[] chain = new Certificate[1];
            chain[0] = self_signed_cert;
            PrivateKeyEntry entry = new PrivateKeyEntry(kp.getPrivate(), chain);

            //
            // Set the entry using the label as the alias and save the store.
            // The alias must match the private key label.
            //
            keyStore.setEntry(label, entry, passwd);

            FileOutputStream outstream = new FileOutputStream(keystoreFile);
            keyStore.store(outstream, password.toCharArray());
            outstream.close();

            keyEntry = (PrivateKeyEntry) keyStore.getEntry(label, passwd);
        }

        long handle = ((CaviumKey) keyEntry.getPrivateKey()).getHandle();
        String name = keyEntry.getCertificate().toString();
        System.out.printf("Found private key %d with certificate %s%n", handle, name);
    }

    private static void help() {
        System.out.println(helpString);
    }

    //
    // Generate a non-extractable / non-persistent RSA keypair.
    // This method allows us to specify the public and private labels, which
    // will make KeyStore aliases easier to understand.
    //
    public static KeyPair generateRSAKeyPair(int keySizeInBits, String publicLabel, String privateLabel)
            throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException {

        boolean isExtractable = false;
        boolean isPersistent = false;
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("rsa", "Cavium");
        CaviumRSAKeyGenParameterSpec spec = new CaviumRSAKeyGenParameterSpec(keySizeInBits, new BigInteger("65537"), publicLabel, privateLabel, isExtractable, isPersistent);

        keyPairGen.initialize(spec);

        return keyPairGen.generateKeyPair();
    }

    //
    // Generate a certificate signed by a given keypair.
    //
    private static Certificate generateCert(KeyPair kp) throws CertificateException {
        CertificateFactory cf = CertificateFactory.getInstance("X509");
        PublicKey publicKey = kp.getPublic();
        PrivateKey privateKey = kp.getPrivate();
        byte[] version = Encoder.encodeConstructed((byte) 0, Encoder.encodePositiveBigInteger(new BigInteger("2"))); // version 1
        byte[] serialNo = Encoder.encodePositiveBigInteger(new BigInteger(1, Util.computeKCV(publicKey.getEncoded())));

        // Use the SHA512 OID and algorithm.
        byte[] signatureOid = new byte[] {
            (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x0D };
        String sigAlgoName = "SHA512WithRSA";

         byte[] signatureId = Encoder.encodeSequence(
                                         Encoder.encodeOid(signatureOid),
                                         Encoder.encodeNull());

         byte[] issuer = Encoder.encodeSequence(
                                     encodeName(COUNTRY_NAME_OID, "<Country>"),
                                     encodeName(STATE_OR_PROVINCE_NAME_OID, "<State>"),
                                     encodeName(LOCALITY_NAME_OID, "<City>"),
                                     encodeName(ORGANIZATION_NAME_OID, "<Organization>"),
                                     encodeName(ORGANIZATION_UNIT_OID, "<Unit>"),
                                     encodeName(COMMON_NAME_OID, "<CN>")
                                 );

         Calendar c = Calendar.getInstance();
         c.add(Calendar.DAY_OF_YEAR, -1);
         Date notBefore = c.getTime();
         c.add(Calendar.YEAR, 1);
         Date notAfter = c.getTime();
         byte[] validity = Encoder.encodeSequence(
                                         Encoder.encodeUTCTime(notBefore),
                                         Encoder.encodeUTCTime(notAfter)
                                     );
         byte[] key = publicKey.getEncoded();

         byte[] certificate = Encoder.encodeSequence(
                                         version,
                                         serialNo,
                                         signatureId,
                                         issuer,
                                         validity,
                                         issuer,
                                         key);
         Signature sig;
         byte[] signature = null;
         try {
             sig = Signature.getInstance(sigAlgoName, "Cavium");
             sig.initSign(privateKey);
             sig.update(certificate);
             signature = Encoder.encodeBitstring(sig.sign());

         } catch (Exception e) {
             System.err.println(e.getMessage());
             return null;
         }

         byte [] x509 = Encoder.encodeSequence(
                         certificate,
                         signatureId,
                         signature
                         );
         return cf.generateCertificate(new ByteArrayInputStream(x509));
    }

     //
     // Simple OID encoder.
     // Encode a value with OID in ASN.1 format
     //
     private static byte[] encodeName(byte[] nameOid, String value) {
         byte[] name = null;
         name = Encoder.encodeSet(
                     Encoder.encodeSequence(
                             Encoder.encodeOid(nameOid),
                             Encoder.encodePrintableString(value)
                     )
                 );
         return name;
     }

    //
    // List all the keys in the keystore.
    //
    private static void listKeys(String keystoreFile, String password) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("CloudHSM");

        try {
            FileInputStream instream = new FileInputStream(keystoreFile);
            keyStore.load(instream, password.toCharArray());
        } catch (FileNotFoundException ex) {
            System.err.println("Keystore not found, loading an empty store");
            keyStore.load(null, null);
        }

        for(Enumeration<String> entry = keyStore.aliases(); entry.hasMoreElements();) {
            System.out.println(entry.nextElement());
        }
    }

}
```