

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Use o Client SDK 3 para fazer a integração AWS CloudHSM com o Java Keytool e o Jarsigner
<a name="keystore-third-party-tools"></a>

AWS CloudHSM O armazenamento de chaves é um armazenamento de chaves JCE para fins especiais que utiliza certificados associados às chaves em seu módulo de segurança de hardware (HSM) por meio de ferramentas de terceiros, como e. `keytool` `jarsigner` AWS CloudHSM não armazena certificados no HSM, pois os certificados são dados públicos e não confidenciais. O armazenamento de AWS CloudHSM chaves armazena os certificados em um arquivo local e mapeia os certificados para as chaves correspondentes no seu HSM. 

Quando você usa o armazenamento de AWS CloudHSM chaves para gerar novas chaves, nenhuma entrada é gerada no arquivo de armazenamento de chaves local — as chaves são criadas no HSM. Da mesma forma, quando você usa o repositório de chaves do AWS CloudHSM para procurar chaves, a pesquisa é transmitida para o HSM. Quando você armazena certificados no armazenamento de AWS CloudHSM chaves, o provedor verifica se existe um par de chaves com o alias correspondente no HSM e, em seguida, associa o certificado fornecido ao par de chaves correspondente. 

**Topics**
+ [Pré-requisitos](keystore-prerequisites.md)
+ [Usar o repositório de chaves com o keytool](using_keystore_with_keytool.md)
+ [Usar o repositório de chaves com jarsigner](using_keystore_jarsigner.md)
+ [Problemas conhecidos](known-issues-keytool-jarsigner.md)
+ [Registrar chaves pré-existentes com o repositório de chaves](register-pre-existing-keys-with-keystore.md)

# Pré-requisitos para integração AWS CloudHSM com Java Keytool e Jarsigner usando o Client SDK 3
<a name="keystore-prerequisites"></a>

Para usar o armazenamento de AWS CloudHSM chaves, primeiro você deve inicializar e configurar o SDK do AWS CloudHSM JCE. Para isso, siga as etapas a seguir. 

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

Para instalar o JCE, incluindo os pré-requisitos AWS CloudHSM do cliente, siga as etapas para [instalar](java-library-install.md) a biblioteca Java. 

## Etapa 2: Adicionar credenciais de login do HSM a variáveis de ambiente
<a name="prereq-step-two"></a>

Configure variáveis de ambiente para conter suas credenciais de login do HSM. 

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

**nota**  
O CloudHSM JCE oferece várias opções de login. Para usar o armazenamento de AWS CloudHSM chaves com aplicativos de terceiros, você deve usar o login implícito com variáveis de ambiente. Se você quiser usar o login explícito por meio do código do aplicativo, deverá criar seu próprio aplicativo usando o armazenamento de AWS CloudHSM chaves. Para obter informações adicionais, consulte o artigo sobre [Como usar o armazenamento de AWS CloudHSM chaves](alternative-keystore.md). 

## Etapa 3: Registrar o provedor JCE
<a name="prereq-step-three"></a>

Para registrar o provedor JCE, na CloudProvider configuração Java. 

1. Abra o arquivo de configuração java.security em sua instalação Java para edição.

1. No arquivo de configuração java.security, adicione `com.cavium.provider.CaviumProvider` como o último provedor. Por exemplo, se houver nove provedores no arquivo java.security, adicione o provedor a seguir como o último provedor na seção. Adicionar o provedor Cavium como prioridade maior pode afetar negativamente o desempenho do seu sistema.

   `security.provider.10=com.cavium.provider.CaviumProvider`
**nota**  
Usuários avançados podem estar acostumados a especificar opções de linha de comando `-providerName`, `-providerclass` e `-providerpath` ao usar o keytool, em vez de atualizar o arquivo de configuração de segurança. Se você tentar especificar as opções da linha de comando ao gerar chaves com o armazenamento de AWS CloudHSM chaves, isso causará erros. 

# Use o armazenamento de AWS CloudHSM chaves com o keytool usando o Client SDK 3
<a name="using_keystore_with_keytool"></a>

[ Keytool](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html) é um utilitário de linha de comando popular para tarefas comuns de chave e certificado em sistemas Linux. Um tutorial completo sobre o keytool está fora do escopo da documentação do AWS CloudHSM . Este artigo explica os parâmetros específicos que você deve usar com várias funções de ferramentas-chave ao utilizá-las AWS CloudHSM como raiz de confiança por meio do armazenamento de AWS CloudHSM chaves.

Ao usar o keytool com o armazenamento de AWS CloudHSM chaves, especifique os seguintes argumentos para qualquer comando keytool:

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

Se você quiser criar um novo arquivo de armazenamento de chaves usando o armazenamento de AWS CloudHSM chaves, consulte[Use o AWS CloudHSM KeyStore for AWS CloudHSM Client SDK 3](alternative-keystore.md#using_cloudhsm_keystore). Para usar um armazenamento de chaves existente, especifique seu nome (incluindo o caminho) usando o argumento keystore para keytool. Se você especificar um arquivo de armazenamento de chaves inexistente em um comando keytool, o armazenamento de AWS CloudHSM chaves criará um novo arquivo de armazenamento de chaves.

# Crie novas AWS CloudHSM chaves com o keytool
<a name="create_key_keytool"></a>

Você pode usar o keytool para gerar qualquer tipo de chave compatível com o SDK do AWS CloudHSM JCE. Veja uma lista completa de chaves e comprimentos no artigo [ Chaves Suportadas](java-lib-supported.md#java-keys) na Biblioteca Java.

**Importante**  
Uma chave gerada por meio do keytool é gerada no software e depois importada AWS CloudHSM como uma chave persistente e extraível.

As instruções para criar chaves não extraíveis diretamente no módulo de segurança de hardware (HSM) e depois usá-las com o keytool ou o Jarsigner são mostradas na amostra de código em [Registrando](register-pre-existing-keys-with-keystore.md) chaves pré-existentes no Key Store. AWS CloudHSM É altamente recomendável gerar chaves não exportáveis fora do keytool e importar certificados correspondentes para o repositório de chaves. Se você usar chaves RSA ou EC extraíveis por meio de keytool e jarsigner, os provedores exportarão as chaves do e, em seguida, usarão a chave AWS CloudHSM localmente para operações de assinatura.

Se você tiver várias instâncias de cliente conectadas ao cluster do CloudHSM, esteja ciente de que importar um certificado no repositório de chaves de uma instância de cliente não disponibilizará automaticamente os certificados em outras instâncias de cliente. Para registrar a chave e os certificados associados em cada instância do cliente, você precisa executar um aplicativo Java conforme descrito em [Gerar um CSR usando Keytool](generate_csr_using_keytool.md). Como alternativa, você pode fazer as alterações necessárias em um cliente e copiar o arquivo repositório de chaves resultante para todas as outras instâncias de cliente.

**Exemplo 1: **para gerar uma chave AES-256 simétrica e salvá-la em um arquivo armazenamento de chave chamado “example\$1keystore.store”, no diretório de trabalho. *<secret label>*Substitua por uma etiqueta exclusiva.

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

**Exemplo 2: **para gerar um par de chaves RSA 2048 e salvá-lo em um arquivo armazenamento de chave chamado “example\$1keystore.store”, no diretório de trabalho. *<RSA key pair label>*Substitua por uma etiqueta exclusiva.

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

**Exemplo 3: **para gerar um par de chaves p256 ED e salvá-lo em um arquivo armazenamento de chave chamado “example\$1keystore.store”, no diretório de trabalho. *<ec key pair label>*Substitua por uma etiqueta exclusiva.

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

Você pode encontrar uma lista de [algoritmos de assinatura suportados](java-lib-supported.md#java-sign-verify) na biblioteca Java.

# Exclua uma AWS CloudHSM chave usando o keytool
<a name="delete_key_using_keytool"></a>

O armazenamento de AWS CloudHSM chaves não suporta a exclusão de chaves. Para excluir a chave, você deve usar a `deleteKey` função AWS CloudHSM da ferramenta de linha de comando,[Excluir uma AWS CloudHSM chave usando KMU](key_mgmt_util-deleteKey.md).

# Gere uma AWS CloudHSM CSR usando o keytool
<a name="generate_csr_using_keytool"></a>

Você recebe a maior flexibilidade na geração de um pedido de assinatura de certificado (CSR) se você usar o [Mecanismo AWS CloudHSM dinâmico OpenSSL para cliente SDK 5](openssl-library.md). O comando a seguir usa o keytool para gerar um CSR para um par de chaves com o 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 usar um par de chaves da keytool, esse par de chaves deve ter uma entrada no arquivo de repositório de chaves especificado. Se você quiser usar um par de chaves que foi gerado fora do keytool, você deve importar os metadados de chave e certificado para o repositório de chaves. Para obter instruções sobre como importar os dados do armazenamento de chaves, consulte [Importação de certificados intermediários e raiz para o AWS CloudHSM Key Store](import_cert_using_keytool.md) usando o Keytool.

# Use o keytool para importar certificados intermediários e raiz para o armazenamento de AWS CloudHSM chaves
<a name="import_cert_using_keytool"></a>

Para importar um certificado CA para AWS CloudHSM, você deve habilitar a verificação de uma cadeia de certificados completa em um certificado recém-importado. O seguinte comando mostra um exemplo. 

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

Se você conectar várias instâncias do cliente ao seu AWS CloudHSM cluster, importar um certificado no armazenamento de chaves de uma instância do cliente não disponibilizará automaticamente o certificado em outras instâncias do cliente. Você deve importar o certificado em cada instância do cliente.

# Use o keytool para excluir certificados do armazenamento de AWS CloudHSM chaves
<a name="delete_cert_using_keytool"></a>

O comando a seguir mostra um exemplo de como excluir um AWS CloudHSM certificado de um armazenamento de chaves Java keytool. 

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

Se você conectar várias instâncias do cliente ao seu AWS CloudHSM cluster, a exclusão de um certificado no armazenamento de chaves de uma instância do cliente não removerá automaticamente o certificado de outras instâncias do cliente. Você deve excluir o certificado em cada instância de cliente.

# Importe um certificado funcional para o armazenamento de AWS CloudHSM chaves usando o keytool
<a name="import_working_cert_using_keytool"></a>

Depois que uma solicitação de assinatura de certificado (CSR) for assinada, você poderá importá-la para o repositório de chaves do AWS CloudHSM e associá-la ao par de chaves apropriado. O comando a seguir fornece um exemplo. 

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

O alias deve ser um par de chaves com um certificado associado no repositório de chaves. Se a chave for gerada fora da ferramenta de chave ou for gerada em uma instância de cliente diferente, você deve primeiro importar os metadados de chave e certificado para o repositório de chaves. Para obter instruções sobre como importar os metadados do certificado, consulte o exemplo de código em [Registrando chaves pré-existentes](register-pre-existing-keys-with-keystore.md) com o Key Store. AWS CloudHSM 

A cadeia de certificados deve ser verificável. Se você não conseguir verificar o certificado, talvez seja necessário importar o certificado de assinatura (autoridade de certificação) para o repositório de chaves para que a cadeia possa ser verificada.

# Exportar um certificado AWS CloudHSM usando o keytool
<a name="export_cert_using_keytool"></a>

O exemplo a seguir gera um certificado no formato binário X.509. Para exportar um certificado legível por humanos de AWS CloudHSM, adicione `-rfc` ao `-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/
```

# Use o armazenamento de AWS CloudHSM chaves com o Jarsigner usando o Client SDK 3
<a name="using_keystore_jarsigner"></a>

Jarsigner é um utilitário de linha de comando popular para assinar arquivos JAR usando uma chave armazenada de forma segura em um HSM. Um tutorial completo sobre o Jarsigner está fora do escopo da AWS CloudHSM documentação. Esta seção explica os parâmetros do Jarsigner que você deve usar para assinar e verificar assinaturas AWS CloudHSM como raiz de confiança por meio do AWS CloudHSM armazenamento de chaves. 

# Configure AWS CloudHSM chaves e certificados com o Jarsigner
<a name="jarsigner_set_up_certificates"></a>

Antes de assinar arquivos AWS CloudHSM JAR com o Jarsigner, certifique-se de ter configurado ou concluído as seguintes etapas: 

1. Siga as orientações nos [pré-requisitos de repositório de chaves AWS CloudHSM](keystore-prerequisites.md).

1. Configure suas chaves de assinatura e os certificados associados e a cadeia de certificados, que devem ser armazenados no armazenamento de AWS CloudHSM chaves da instância atual do servidor ou cliente. Crie as chaves no AWS CloudHSM e, em seguida, importe os metadados associados para o seu armazenamento de AWS CloudHSM chaves. Use o exemplo de código em [Registrando chaves pré-existentes com o AWS CloudHSM Key Store](register-pre-existing-keys-with-keystore.md) para importar metadados para o armazenamento de chaves. Se você quiser usar o keytool para configurar as chaves e certificados, consulte [Crie novas AWS CloudHSM chaves com o keytool](create_key_keytool.md). Se você usar várias instâncias de cliente para assinar sua JARs, crie a chave e importe a cadeia de certificados. Em seguida, copie o arquivo de repositório de chaves resultante para cada instância do cliente. Se você gerar novas chaves com frequência, talvez seja mais fácil importar certificados individualmente para cada instância do cliente.

1. Toda a cadeia de certificados deve ser verificável. Para que a cadeia de certificados seja verificável, talvez seja necessário adicionar o certificado CA e os certificados intermediários ao armazenamento de AWS CloudHSM chaves. Consulte o trecho de código em [Assine um arquivo JAR usando AWS CloudHSM e Jarsigner](jarsigner_sign_jar_using_hsm_jarsigner.md) para obter instruções sobre como usar o código Java para verificar a cadeia de certificados. Se preferir, você pode usar o keytool para importar certificados. Para obter instruções sobre como usar o keytool, consulte [Usando o Keytool para importar certificados intermediários e raiz para o AWS CloudHSM Key Store](import_cert_using_keytool.md). 

# Assine um arquivo JAR usando AWS CloudHSM e Jarsigner
<a name="jarsigner_sign_jar_using_hsm_jarsigner"></a>

Use o comando a seguir para assinar um arquivo JAR usando o AWS CloudHSM 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>
```

Use o seguinte comando para verificar um JAR assinado: 

```
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 conhecidos para AWS CloudHSM integração Java Keytool e Jarsigner usando o Client SDK 3
<a name="known-issues-keytool-jarsigner"></a>

A lista a seguir fornece a lista atual de problemas conhecidos de integrações com Java Keytool AWS CloudHSM e Jarsigner usando o Client SDK 3. 
+ Ao gerar chaves usando o keytool, o primeiro provedor na configuração do provedor não pode ser CaviumProvider. 
+ Ao gerar chaves usando keytool, o primeiro provedor (compatível) no arquivo de configuração de segurança é usado para gerar a chave. Geralmente é um provedor de software. Em seguida, a chave gerada recebe um alias e é importada para o AWS CloudHSM HSM como uma chave persistente (token) durante o processo de adição da chave. 
+  Ao usar o keytool com o armazenamento de AWS CloudHSM chaves, não especifique `-providerName` nem `-providerpath` as opções na linha de comando. `-providerclass` Especifique essas opções no arquivo do provedor de segurança, conforme descrito nos [pré-requisitos do repositório de chaves](keystore-prerequisites.md). 
+ Ao usar chaves EC não extraíveis por meio do keytool e do Jarsigner, o provedor SunEC precisa removed/disabled estar na lista de provedores no arquivo java.security. Se você usar chaves EC extraíveis por meio do keytool e do Jarsigner, os provedores exportarão bits de chave do AWS CloudHSM HSM e usarão a chave localmente para operações de assinatura. Não recomendamos o uso de chaves exportáveis com keytool ou Jarsigner.

# Registre chaves pré-existentes com o armazenamento de AWS CloudHSM chaves
<a name="register-pre-existing-keys-with-keystore"></a>

Para máxima segurança e flexibilidade em atributos e rótulos, recomendamos que você gere suas chaves de AWS CloudHSM assinatura usando [key\$1mgmt\$1util](generate-keys.md). Você também pode usar um aplicativo Java para gerar a chave no AWS CloudHSM.

A seção a seguir fornece um exemplo de código que demonstra como gerar um novo par de chaves no HSM e registrá-lo usando chaves existentes importadas para o AWS CloudHSM armazenamento de chaves. As chaves importadas estão disponíveis para uso com ferramentas de terceiros, como keytool e Jarsigner. 

Para usar uma chave pré-existente, modifique o exemplo de código para procurar uma chave por rótulo em vez de gerar uma nova chave. O código de amostra para pesquisar uma chave por rótulo está disponível na [amostra KeyUtilitiesRunner .java](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/master/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java) em GitHub. 

**Importante**  
Registrar uma chave AWS CloudHSM armazenada em um repositório de chaves local não exporta a chave. Quando a chave é registrada, o repositório de chaves registra o alias (ou rótulo) da chave e correlaciona localmente objetos de certificado de armazenamento com um par de chaves no AWS CloudHSM. Desde que o par de chaves seja criado como não exportável, os bits de chave não sairão do 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());
        }
    }

}
```