

# JCE provider for AWS CloudHSM Client SDK 5
<a name="java-library"></a>

The AWS CloudHSM JCE provider is a provider implementation built from the Java Cryptographic Extension (JCE) provider framework. The JCE allows you to perform cryptographic operations using the Java Development Kit (JDK). In this guide, the AWS CloudHSM JCE provider is sometimes referred to as the JCE provider. Use the JCE provider and the JDK to offload cryptographic operations to the HSM. For troubleshooting, see [Known issues for the JCE SDK for AWS CloudHSM](ki-jce-sdk.md).

For information on using Client SDK 3, see [Using previous SDK version to work with AWS CloudHSM](choose-client-sdk.md).

**Topics**
+ [Install the JCE provider for AWS CloudHSM Client SDK 5](java-library-install_5.md)
+ [Supported key types for JCE provider for AWS CloudHSM Client SDK 5](java-lib-keys_5.md)
+ [Key management basics in the JCE provider for AWS CloudHSM Client SDK 5](java-library-key-basics_5.md)
+ [Supported mechanisms for JCE provider for AWS CloudHSM Client SDK 5](java-lib-supported_5.md)
+ [Supported Java key attributes for AWS CloudHSM Client SDK 5](java-lib-attributes_5.md)
+ [Code samples for the AWS CloudHSM software library for Java for Client SDK 5](java-samples.md)
+ [AWS CloudHSM JCE provider Javadocs](java-javadocs_5.md)
+ [AWS CloudHSM KeyStore Java class for Client SDK 5](alternative-keystore_5.md)
+ [Advanced configurations for AWS CloudHSM JCE for Client SDK 5](java-lib-configs.md)

# Install the JCE provider for AWS CloudHSM Client SDK 5
<a name="java-library-install_5"></a>

The JCE provider for AWS CloudHSM Client SDK 5 is compatible with OpenJDK 8, OpenJDK 11, OpenJDK 17, OpenJDK 21, and OpenJDK 25. You can download both from the [OpenJDK website](https://openjdk.java.net/).

Use the following sections to install and provide credentials to the provider.

**Note**  
To run a single HSM cluster with Client SDK 5, you must first manage client key durability settings by setting `disable_key_availability_check` to `True`. For more information, see [Key Synchronization](manage-key-sync.md) and [Client SDK 5 Configure Tool](configure-sdk-5.md).

**Topics**
+ [Step 1: Install the JCE provider](#install-java-library_5)
+ [Step 2: Provide credentials to the JCE provider](#java-library-credentials_5)

## Step 1: Install the JCE provider
<a name="install-java-library_5"></a>

1. Use the following commands to download and install the JCE provider. 

------
#### [ Amazon Linux 2023 ]

   Install the JCE provider for Amazon Linux 2023 on x86\$164 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/Amzn2023/cloudhsm-jce-latest.amzn2023.x86_64.rpm
   ```

   ```
   $ sudo yum install ./cloudhsm-jce-latest.amzn2023.x86_64.rpm
   ```

   Install the JCE provider for Amazon Linux 2023 on ARM64 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/Amzn2023/cloudhsm-jce-latest.amzn2023.aarch64.rpm
   ```

   ```
   $ sudo yum install ./cloudhsm-jce-latest.amzn2023.aarch64.rpm
   ```

------
#### [ Amazon Linux 2 ]

   Install the JCE provider for Amazon Linux 2 on x86\$164 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL7/cloudhsm-jce-latest.el7.x86_64.rpm
   ```

   ```
   $ sudo yum install ./cloudhsm-jce-latest.el7.x86_64.rpm
   ```

   Install the JCE provider for Amazon Linux 2 on ARM64 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL7/cloudhsm-jce-latest.el7.aarch64.rpm
   ```

   ```
   $ sudo yum install ./cloudhsm-jce-latest.el7.aarch64.rpm
   ```

------
#### [ RHEL 10 (10.0\$1) ]

   Install the JCE provider for RHEL 10 on x86\$164 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL10/cloudhsm-jce-latest.el10.x86_64.rpm
   ```

   ```
   $ sudo yum install ./cloudhsm-jce-latest.el10.x86_64.rpm
   ```

   Install the JCE provider for RHEL 10 on ARM64 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL10/cloudhsm-jce-latest.el10.aarch64.rpm
   ```

   ```
   $ sudo yum install ./cloudhsm-jce-latest.el10.aarch64.rpm
   ```

------
#### [ RHEL 9 (9.2\$1) ]

   Install the JCE provider for RHEL 9 (9.2\$1) on x86\$164 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL9/cloudhsm-jce-latest.el9.x86_64.rpm
   ```

   ```
   $ sudo yum install ./cloudhsm-jce-latest.el9.x86_64.rpm
   ```

   Install the JCE provider for RHEL 9 (9.2\$1) on ARM64 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL9/cloudhsm-jce-latest.el9.aarch64.rpm
   ```

   ```
   $ sudo yum install ./cloudhsm-jce-latest.el9.aarch64.rpm
   ```

------
#### [ RHEL 8 (8.3\$1) ]

   Install the JCE provider for RHEL 8 on x86\$164 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL8/cloudhsm-jce-latest.el8.x86_64.rpm
   ```

   ```
   $ sudo yum install ./cloudhsm-jce-latest.el8.x86_64.rpm
   ```

   Install the JCE provider for RHEL 8 on ARM64 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL8/cloudhsm-jce-latest.el8.aarch64.rpm
   ```

   ```
   $ sudo yum install ./cloudhsm-jce-latest.el8.aarch64.rpm
   ```

------
#### [ Ubuntu 24.04 LTS ]

   Install the JCE provider for Ubuntu 24.04 LTS on x86\$164 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/Noble/cloudhsm-jce_latest_u24.04_amd64.deb
   ```

   ```
   $ sudo apt install ./cloudhsm-jce_latest_u24.04_amd64.deb
   ```

   Install the JCE provider for Ubuntu 24.04 LTS on ARM64 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/Noble/cloudhsm-jce_latest_u24.04_arm64.deb
   ```

   ```
   $ sudo apt install ./cloudhsm-jce_latest_u24.04_arm64.deb
   ```

------
#### [ Ubuntu 22.04 LTS ]

   Install the JCE provider for Ubuntu 22.04 LTS on x86\$164 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/Jammy/cloudhsm-jce_latest_u22.04_amd64.deb
   ```

   ```
   $ sudo apt install ./cloudhsm-jce_latest_u22.04_amd64.deb
   ```

   Install the JCE provider for Ubuntu 22.04 LTS on ARM64 architecture:

   ```
   $ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/Jammy/cloudhsm-jce_latest_u22.04_arm64.deb
   ```

   ```
   $ sudo apt install ./cloudhsm-jce_latest_u22.04_arm64.deb
   ```

------
#### [ Windows Server ]

   Install the JCE provider for Windows Server on x86\$164 architecture, open PowerShell as an administrator and run the following command:

   ```
   PS C:\> wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/Windows/AWSCloudHSMJCE-latest.msi -Outfile C:\AWSCloudHSMJCE-latest.msi
   ```

   ```
   PS C:\> Start-Process msiexec.exe -ArgumentList '/i C:\AWSCloudHSMJCE-latest.msi /quiet /norestart /log C:\client-install.txt' -Wait
   ```

------

1. Bootstrap Client SDK 5. For more information about bootstrapping, see [Bootstrap the Client SDK](cluster-connect.md#connect-how-to).

1. Locate the following JCE provider files:

------
#### [ Linux ]
   + `/opt/cloudhsm/java/cloudhsm-<version>.jar`
   + `/opt/cloudhsm/bin/configure-jce`
   + `/opt/cloudhsm/bin/jce-info`

------
#### [ Windows ]
   + `C:\Program Files\Amazon\CloudHSM\java\cloudhsm-<version>.jar>`
   + `C:\Program Files\Amazon\CloudHSM\bin\configure-jce.exe`
   + `C:\Program Files\Amazon\CloudHSM\bin\jce_info.exe`

------

## Step 2: Provide credentials to the JCE provider
<a name="java-library-credentials_5"></a>

Before your Java application can use an HSM, the HSM needs to first authenticate the application. HSMs authenticate using either an explicit login or implicit login method.

**Explicit login** – This method lets you provide AWS CloudHSM credentials directly in the application. It uses the method from the [https://docs.oracle.com/javase/8/docs/api/java/security/AuthProvider.html](https://docs.oracle.com/javase/8/docs/api/java/security/AuthProvider.html), where you pass a CU username and password in the pin pattern. For more information, see [Login to an HSM](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/LoginRunner.java) code example.

**Implicit login** – This method lets you set AWS CloudHSM credentials either in a new property file, system properties, or as environment variables.
+ **System properties** – Set credentials through system properties when running your application. The following examples show two different ways that you can do this:

------
#### [ Linux ]

  ```
  $ java -DHSM_USER=<HSM user name> -DHSM_PASSWORD=<password>
  ```

  ```
  System.setProperty("HSM_USER","<HSM user name>");
  System.setProperty("HSM_PASSWORD","<password>");
  ```

------
#### [ Windows ]

  ```
  PS C:\> java -DHSM_USER=<HSM user name> -DHSM_PASSWORD=<password>
  ```

  ```
  System.setProperty("HSM_USER","<HSM user name>");
  System.setProperty("HSM_PASSWORD","<password>");
  ```

------
+ **Environment variables** – Set credentials as environment variables.
**Note**  
When setting environment variables, you must escape any special characters that may be interpreted by your shell.

------
#### [ Linux ]

  ```
  $ export HSM_USER=<HSM user name>
  $ export HSM_PASSWORD=<password>
  ```

------
#### [ Windows ]

  ```
  PS C:\> $Env:HSM_USER="<HSM user name>"
  PS C:\> $Env:HSM_PASSWORD="<password>"
  ```

------

Credentials might not be available if the application does not provide them or if you attempt an operation before the HSM authenticates session. In those cases, the CloudHSM software library for Java searches for the credentials in the following order:

1. System properties

1. Environment variables

# Supported key types for JCE provider for AWS CloudHSM Client SDK 5
<a name="java-lib-keys_5"></a>

The AWS CloudHSM software library for Java enables you to generate the following key types.


****  

| Key Type | Description | 
| --- | --- | 
| AES | Generate 128, 192, and 256-bit AES keys.  | 
| Triple DES (3DES, DESede) | Generate a 192-bit Triple DES Key [*](#java-lib-keys_5-note-1). | 
| EC | Generate EC key pairs – NIST curves secp224r1 (P-224), secp256r1 (P-256), secp256k1 (Blockchain), secp384r1 (P-384), and secp521r1 (P-521). | 
| GENERIC\$1SECRET | Generate 1 to 800 bytes generic secrets. | 
| HMAC | Hash support for SHA1, SHA224, SHA256, SHA384, SHA512. | 
| RSA | Generate 2048-bit to 4096-bit RSA keys, in increments of 256 bits. | 

\$1 In accordance with NIST guidance, this is disallowed for clusters in FIPS mode after 2023. For clusters in non-FIPS mode, it is still allowed after 2023. See [FIPS 140 Compliance: 2024 Mechanism Deprecation](compliance-dep-notif.md#compliance-dep-notif-1) for details.

# Key management basics in the JCE provider for AWS CloudHSM Client SDK 5
<a name="java-library-key-basics_5"></a>

The basics on key management in the JCE provider involve importing keys, exporting keys, loading keys by handle, or deleting keys. For more information on managing keys, see the [Manage keys](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java) code example.

You can also find more JCE provider code examples at [Code samples](java-samples.md).

# Supported mechanisms for JCE provider for AWS CloudHSM Client SDK 5
<a name="java-lib-supported_5"></a>

This topic provides information about supported mechanisms for JCE provider with AWS CloudHSM Client SDK 5. For information about the Java Cryptography Architecture (JCA) interfaces and engine classes supported by AWS CloudHSM, see the following topics. 

**Topics**
+ [Generate key and key pair functions](#java-gen-key-pairs-5)
+ [Cipher functions](#java-ciphers_5)
+ [Sign and verify functions](#java-sign-verify_5)
+ [Digest functions](#java-digests_5)
+ [Hash-based message authentication code (HMAC) functions](#java-mac_5)
+ [Cipher-based message authentication code (CMAC) functions](#java-cmac_5)
+ [Key Agreement Functions](#java-key-derivation_5)
+ [Convert keys to key specifications using key factories](#java-key-factories)
+ [Mechanism annotations](#w2aac25c21c25c15c23)

## Generate key and key pair functions
<a name="java-gen-key-pairs-5"></a>

The AWS CloudHSM software library for Java allows you to use the following operations for generate key and key pair functions.
+ `RSA`
+ `EC`
+ `AES`
+ `DESede (Triple DES)`see note [1](#java-gen-key-pairs-5-note-1)
+ `GenericSecret`

## Cipher functions
<a name="java-ciphers_5"></a>

The AWS CloudHSM software library for Java supports the following algorithm, mode, and padding combinations.


| Algorithm | Mode | Padding | Notes | 
| --- | --- | --- | --- | 
| AES | CBC |  `AES/CBC/NoPadding` `AES/CBC/PKCS5Padding`  |  Implements `Cipher.ENCRYPT_MODE` and `Cipher.DECRYPT_MODE`. Implements `Cipher.UNWRAP_MODE for AES/CBC NoPadding`  | 
| AES | ECB |  `AES/ECB/PKCS5Padding` `AES/ECB/NoPadding`  | Implements `Cipher.ENCRYPT_MODE` and `Cipher.DECRYPT_MODE`.  | 
| AES | CTR |  `AES/CTR/NoPadding`  |  Implements `Cipher.ENCRYPT_MODE` and `Cipher.DECRYPT_MODE`.  | 
| AES | GCM | `AES/GCM/NoPadding` | Implements `Cipher.WRAP_MODE`, `Cipher.UNWRAP_MODE`, `Cipher.ENCRYPT_MODE`, and `Cipher.DECRYPT_MODE`.When performing AES-GCM encryption, the HSM ignores the initialization vector (IV) in the request and uses an IV that it generates. When the operation completes, you must call `Cipher.getIV()` to get the IV. | 
| AESWrap | ECB |  `AESWrap/ECB/NoPadding` `AESWrap/ECB/PKCS5Padding` `AESWrap/ECB/ZeroPadding`  | Implements `Cipher.WRAP_MODE` and `Cipher.UNWRAP_MODE`.  | 
| DESede (Triple DES) | CBC |  `DESede/CBC/PKCS5Padding` `DESede/CBC/NoPadding`  |  Implements `Cipher.ENCRYPT_MODE` and `Cipher.DECRYPT_MODE`. See note [1](#java-gen-key-pairs-5-note-1) below for an upcoming change.  | 
| DESede (Triple DES) | ECB |  `DESede/ECB/NoPadding` `DESede/ECB/PKCS5Padding`  | Implements `Cipher.ENCRYPT_MODE` and `Cipher.DECRYPT_MODE`. See note [1](#java-gen-key-pairs-5-note-1) below for an upcoming change.  | 
| RSA | ECB | `RSA/ECB/PKCS1Padding` **see note [1](#java-gen-key-pairs-5-note-1)** `RSA/ECB/OAEPPadding` `RSA/ECB/OAEPWithSHA-1ANDMGF1Padding` `RSA/ECB/OAEPWithSHA-224ANDMGF1Padding` `RSA/ECB/OAEPWithSHA-256ANDMGF1Padding` `RSA/ECB/OAEPWithSHA-384ANDMGF1Padding` `RSA/ECB/OAEPWithSHA-512ANDMGF1Padding`  |  Implements `Cipher.WRAP_MODE`, `Cipher.UNWRAP_MODE`, `Cipher.ENCRYPT_MODE`, and `Cipher.DECRYPT_MODE`.  | 
| RSA | ECB | `RSA/ECB/NoPadding` |  Implements `Cipher.ENCRYPT_MODE` and `Cipher.DECRYPT_MODE`.  | 
| RSAAESWrap | ECB |  `RSAAESWrap/ECB/OAEPPadding` `RSAAESWrap/ECB/OAEPWithSHA-1ANDMGF1Padding` `RSAAESWrap/ECB/OAEPWithSHA-224ANDMGF1Padding` `RSAAESWrap/ECB/OAEPWithSHA-256ANDMGF1Padding` `RSAAESWrap/ECB/OAEPWithSHA-384ANDMGF1Padding` `RSAAESWrap/ECB/OAEPWithSHA-512ANDMGF1Padding`  | Implements `Cipher.WRAP_MODE` and `Cipher.UNWRAP_MODE`.  | 

## Sign and verify functions
<a name="java-sign-verify_5"></a>

The AWS CloudHSM software library for Java supports the following types of signature and verification. With Client SDK 5 and signature algorithms with hashing, the data is hashed locally in software before being sent to the HSM for the signature/verification. This means there is no limit on the size of the data that can be hashed by the SDK.

**RSA Signature Types**
+ `NONEwithRSA`
+ `RSASSA-PSS`
+ `SHA1withRSA`
+ `SHA1withRSA/PSS`
+ `SHA1withRSAandMGF1`
+ `SHA224withRSA`
+ `SHA224withRSAandMGF1`
+ `SHA224withRSA/PSS`
+ `SHA256withRSA`
+ `SHA256withRSAandMGF1`
+ `SHA256withRSA/PSS`
+ `SHA384withRSA`
+ `SHA384withRSAandMGF1`
+ `SHA384withRSA/PSS`
+ `SHA512withRSA`
+ `SHA512withRSAandMGF1`
+ `SHA512withRSA/PSS`

**ECDSA Signature Types**
+ `NONEwithECDSA`
+ `SHA1withECDSA`
+ `SHA224withECDSA`
+ `SHA256withECDSA`
+ `SHA384withECDSA`
+ `SHA512withECDSA`

## Digest functions
<a name="java-digests_5"></a>

The AWS CloudHSM software library for Java supports the following message digests. With Client SDK 5, the data is hashed locally in software. This means there is no limit on the size of the data that can be hashed by the SDK.
+ `SHA-1`
+ `SHA-224`
+ `SHA-256`
+ `SHA-384`
+ `SHA-512`

## Hash-based message authentication code (HMAC) functions
<a name="java-mac_5"></a>

The AWS CloudHSM software library for Java supports the following HMAC algorithms.
+ `HmacSHA1` (Maximum data size in bytes: 16288)
+ `HmacSHA224` (Maximum data size in bytes: 16256)
+ `HmacSHA256` (Maximum data size in bytes: 16288)
+ `HmacSHA384` (Maximum data size in bytes: 16224)
+ `HmacSHA512` (Maximum data size in bytes: 16224)

## Cipher-based message authentication code (CMAC) functions
<a name="java-cmac_5"></a>

CMACs (Cipher-based message authentication codes) create message authentication codes (MACs) using a block cipher and a secret key. They differ from HMACs in that they use a block symmetric key method for the MACs rather than a hashing method.

The AWS CloudHSM software library for Java supports the following CMAC algorithms.
+ `AESCMAC`

## Key Agreement Functions
<a name="java-key-derivation_5"></a>

The AWS CloudHSM software library for Java supports ECDH with Key Derivation Functions (KDF). The following KDF types are supported:
+ `ECDHwithX963SHA1KDF` Supports X9.63 KDF SHA1 algorithm[2](#kdf2)
+ `ECDHwithX963SHA224KDF` Supports X9.63 KDF SHA224 algorithm[2](#kdf2)
+ `ECDHwithX963SHA256KDF` Supports X9.63 KDF SHA256 algorithm[2](#kdf2)
+ `ECDHwithX963SHA384KDF` Supports X9.63 KDF SHA384 algorithm[2](#kdf2)
+ `ECDHwithX963SHA512KDF` Supports X9.63 KDF SHA512 algorithm[2](#kdf2)

## Convert keys to key specifications using key factories
<a name="java-key-factories"></a>

You can use key factories to convert keys to key specifications. AWS CloudHSM has two types of key factories for JCE:

**SecretKeyFactory:** Used to import or derive symmetric keys. Using SecretKeyFactory, you can pass a supported Key or a supported KeySpec to import or derive symmetric keys into AWS CloudHSM. Following are the supported specs for KeyFactory:
+ For SecretKeyFactory's `generateSecret` method following [KeySpec](https://docs.oracle.com/javase/8/docs/api/java/security/spec/KeySpec.html) classes are supported:
  + **KeyAttributesMap**can be used to import a key bytes with additional attributes as a CloudHSM Key. An example can be found here [here](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java).
  + **[SecretKeySpec](https://docs.oracle.com/javase/8/docs/api/javax/crypto/spec/SecretKeySpec.html)**can be used to import a symmetric key spec as a CloudHSM Key.
  + **AesCmacKdfParameterSpec**can be used to derive symmetric keys using another CloudHSM AES Key.

**Note**  
SecretKeyFactory's `translateKey` method takes any key that implements the [key](https://docs.oracle.com/javase/8/docs/api/java/security/Key.html) interface.

**KeyFactory:** Used for importing asymmetric keys. Using KeyFactory, you can pass a supported Key or supported KeySpec to import an asymmetric key into AWS CloudHSM. For more information, refer to the following resources:
+ For KeyFactory's `generatePublic` method, following [KeySpec](https://docs.oracle.com/javase/8/docs/api/java/security/spec/KeySpec.html) classes are supported:
+ CloudHSM KeyAttributesMap for both RSA and EC KeyTypes, including:
  + CloudHSM KeyAttributesMap for both RSA and EC public KeyTypes. An example can be found [here](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java)
  + [X509EncodedKeySpec](https://docs.oracle.com/javase/8/docs/api/java/security/spec/X509EncodedKeySpec.html) for both RSA and EC Public Key
  + [RSAPublicKeySpec](https://docs.oracle.com/javase/8/docs/api/java/security/spec/RSAPublicKeySpec.html) for RSA Public Key
  + [ECPublicKeySpec](https://docs.oracle.com/javase/8/docs/api/java/security/spec/ECPublicKeySpec.html) for EC Public Key
+ For KeyFactory's `generatePrivate` method, following [KeySpec](https://docs.oracle.com/javase/8/docs/api/java/security/spec/KeySpec.html) classes are supported:
+ CloudHSM KeyAttributesMap for both RSA and EC KeyTypes, including:
  + CloudHSM KeyAttributesMap for both RSA and EC public KeyTypes. An example can be found [here](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java)
  + [PKCS8EncodedKeySpec](https://docs.oracle.com/javase/8/docs/api/java/security/spec/PKCS8EncodedKeySpec.html) for both EC and RSA Private Key
  + [RSAPrivateCrtKeySpec](https://docs.oracle.com/javase/8/docs/api/java/security/spec/RSAPrivateCrtKeySpec.html) for RSA Private Key
  + [ECPrivateKeySpec](https://docs.oracle.com/javase/8/docs/api/java/security/spec/ECPrivateKeySpec.html) for EC Private Key

For KeyFactory's `translateKey` method, it takes in any Key that implements the [Key Interface](https://docs.oracle.com/javase/8/docs/api/java/security/Key.html).

## Mechanism annotations
<a name="w2aac25c21c25c15c23"></a>

[1] In accordance with NIST guidance, this is disallowed for clusters in FIPS mode after 2023. For clusters in non-FIPS mode, it is still allowed after 2023. See [FIPS 140 Compliance: 2024 Mechanism Deprecation](compliance-dep-notif.md#compliance-dep-notif-1) for details.

[2] Key derivation functions (KDFs) are specified in [NIST Special Publication 800-56A Revision 3](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf).

# Supported Java key attributes for AWS CloudHSM Client SDK 5
<a name="java-lib-attributes_5"></a>

This topic provides information about supported Java key attributes for AWS CloudHSM Client SDK 5. This topic describes how to use a proprietary extension for the JCE provider to set key attributes. Use this extension to set supported key attributes and their values during these operations:
+ Key generation
+ Key import

For examples of how to use key attributes, see [Code samples for the AWS CloudHSM software library for Java for Client SDK 5](java-samples.md).

**Topics**
+ [Understanding attributes](#java-understanding-attributes_5)
+ [Supported attributes](#java-attributes_5)
+ [Setting attributes for a key](#java-setting-attributes_5)

## Understanding attributes
<a name="java-understanding-attributes_5"></a>

Use key attributes to specify what actions are permitted on key objects, including public, private or secret keys. Key attributes and values are defined during key object creation operations. 

The Java Cryptography Extension (JCE) does not specify how you should set values on key attributes, so most actions were permitted by default. In contrast, the PKCS\$1 11 standard defines a comprehensive set of attributes with more restrictive defaults. Starting with the JCE provider 3.1, AWS CloudHSM provides a proprietary extension that enables you to set more restrictive values for commonly used attributes. 

## Supported attributes
<a name="java-attributes_5"></a>

You can set values for the attributes listed in the following table. As a best practice, only set values for attributes you wish to make restrictive. If you don’t specify a value, AWS CloudHSM uses the default value specified in the table below. An empty cell in the Default Value columns indicates that there is no specific default value assigned to the attribute.


****  

| Attribute | Default Value | Notes |  | Symmetric Key | Public Key in Key Pair | Private Key in Key Pair |  | 
| --- | --- | --- | --- | --- | --- | --- | --- | 
| DECRYPT | TRUE |  | TRUE | True indicates you can use the key to decrypt any buffer. You generally set this to FALSE for a key whose WRAP is set to true.  | 
| DERIVE |  |  |  | Allows a key to be used to derive other keys. | 
| ENCRYPT | TRUE | TRUE |  | True indicates you can use the key to encrypt any buffer. | 
| EXTRACTABLE | TRUE |  | TRUE | True indicates you can export this key out of the HSM. | 
| ID |  |  |  | A user-defined value used to identify the key. | 
| KEY\$1TYPE |  |  |  | Used to identify the type of key (AES, DESede, generic secret, EC, or RSA). | 
| LABEL |   |  |  | A user-defined string allowing you to conveniently identify keys on your HSM. To follow best practice, use a unique label for each key so it is easier to find later. | 
| LOCAL |  |  |  | Indicates a key generated by the HSM. | 
| OBJECT\$1CLASS |  |  |  | Used to identify the Object Class of a key (SecretKey, PublicKey or PrivateKey). | 
| PRIVATE | TRUE | TRUE | TRUE | True indicates that a user may not access the key until the user is authenticated. For clarity, users cannot access any keys on AWS CloudHSM until they are authenticated, even if this attribute is set to FALSE. | 
| SIGN | TRUE |  | TRUE | True indicates you can use the key to sign a message digest. This is generally set to FALSE for public keys and for private keys that you have archived. | 
| SIZE |  |  |  | An attribute that defines the size of a key. For more details about supported key sizes, refer to [Supported mechanisms for Client SDK 5](https://docs.aws.amazon.com/cloudhsm/latest/userguide/java-lib-supported_5.html#java-keys_5). | 
| TOKEN | FALSE | FALSE | FALSE |  A permanent key which is replicated across all HSMs in the cluster and included in backups. TOKEN = FALSE implies an ephemeral key which is automatically erased when the connection to the HSM is broken or logged out.  | 
| UNWRAP | TRUE |  | TRUE | True indicates you can use the key to unwrap (import) another key. | 
| VERIFY | TRUE | TRUE |  | True indicates you can use the key to verify a signature. This is generally set to FALSE for private keys. | 
| WRAP | TRUE | TRUE |  | True indicates you can use the key to wrap another key. You will generally set this to FALSE for private keys. | 
| WRAP\$1WITH\$1TRUSTED | FALSE |  | FALSE | True indicates a key can only be wrapped and unwrapped with keys that have the TRUSTED attribute set to true. Once a key has WRAP\$1WITH\$1TRUSTED set to true, that attribute is read-only and can’t be set to false. To read about trust wrapping, see [Using trusted keys to control key unwraps](https://docs.aws.amazon.com/cloudhsm/latest/userguide/cloudhsm_using_trusted_keys_control_key_wrap.html). | 

**Note**  
You get broader support for attributes in the PKCS\$111 library. For more information, see [Supported PKCS \$111 Attributes](pkcs11-attributes.md).

## Setting attributes for a key
<a name="java-setting-attributes_5"></a>

`KeyAttributesMap` is a Java Map-like object, which you can use to set attribute values for key objects. The methods for `KeyAttributesMap` function similar to the methods used for Java map manipulation. 

To set custom values on attributes, you have two options:
+ Use the methods listed in the following table
+ Use builder patterns demonstrated later in this document

Attribute map objects support the following methods to set attributes:


****  

| Operation | Return Value | `KeyAttributesMap` method | 
| --- | --- | --- | 
| Get the value of a key attribute for an existing key | Object (containing the value) or null |  **get**(keyAttribute)  | 
| Populate the value of one key attribute  | The previous value associated with key attribute, or null if there was no mapping for a key attribute |  **put**(keyAttribute, value)  | 
| Populate values for multiple key attributes | N/A |  **putAll**(keyAttributesMap)  | 
| Remove a key-value pair from the attribute map |  The previous value associated with key attribute, or *null* if there was no mapping for a key attribute  |  **remove**(keyAttribute)  | 

**Note**  
Any attributes you do not explicitly specify are set to the defaults listed in the preceding table in [Supported attributes](#java-attributes_5). 

### Setting attributes for a key pair
<a name="java-setting-attributes-key-pair"></a>

Use the Java class `KeyPairAttributesMap` to handle key attributes for a key pair. `KeyPairAttributesMap` encapsulates two `KeyAttributesMap` objects; one for a public key and one for a private key.

To set individual attributes for the public key and private key separately, you can use the `put()` method on corresponding `KeyAttributes` map object for that key. Use the `getPublic()` method to retrieve the attribute map for the public key, and use `getPrivate()` to retrieve the attribute map for the private key. Populate the value of multiple key attributes together for both public and private key pairs using the `putAll()` with a key pair attributes map as its argument.

# Code samples for the AWS CloudHSM software library for Java for Client SDK 5
<a name="java-samples"></a>

This topic provides resources and information on Java code samples for AWS CloudHSM Client SDK 5.

## Prerequisites
<a name="java-samples-prereqs_5"></a>

 Before running the samples, you must set up your environment:
+ Install and configure the [Java Cryptographic Extension (JCE) provider](java-library-install_5.md#install-java-library_5). 
+ Set up a valid [HSM user name and password](manage-hsm-users.md). Cryptographic user (CU) permissions are sufficient for these tasks. Your application uses these credentials to log in to the HSM in each example.
+ Decide how to provide credentials to the [JCE provider](java-library-install_5.md#java-library-credentials_5).

## Code samples
<a name="java-samples-code_5"></a>

The following code samples show you how to use the [AWS CloudHSM JCE provider](java-library.md) to perform basic tasks. More code samples are available on [GitHub](https://github.com/aws-samples/aws-cloudhsm-jce-examples/tree/sdk5).
+ [Log in to an HSM](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/LoginRunner.java)
+ [Manage keys](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java)
+ [Generate Symmetric Keys](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/SymmetricKeys.java)
+ [Generate Asymmetric Keys](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/AsymmetricKeys.java)
+ [Encrypt and decrypt with AES-GCM](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/AESGCMEncryptDecryptRunner.java)
+ [Encrypt and decrypt with AES-CTR](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/AESCTREncryptDecryptRunner.java)
+ [Encrypt and decrypt with DESede-ECB](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/DESedeECBEncryptDecryptRunner.java)see note [1](#java-samples-code-5-note-1)
+ [Sign and Verify with RSA Keys](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/RSAOperationsRunner.java)
+ [Sign and Verify with EC Keys](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/ECOperationsRunner.java)
+ [Use supported key attributes](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/KeyAttributesRunner.java)
+ [Use the CloudHSM key store](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/KeyStoreExampleRunner.java)

[1] In accordance with NIST guidance, this is disallowed for clusters in FIPS mode after 2023. For clusters in non-FIPS mode, it is still allowed after 2023. See [FIPS 140 Compliance: 2024 Mechanism Deprecation](compliance-dep-notif.md#compliance-dep-notif-1) for details.

# AWS CloudHSM JCE provider Javadocs
<a name="java-javadocs_5"></a>

Use the JCE provider Javadocs to get usage information on Java types and methods defined in the AWS CloudHSM JCE SDK. To download the latest Javadocs for AWS CloudHSM, see the [AWS CloudHSM latest Client SDK release](latest-releases.md) section on the Downloads page.

You can import Javadocs into an integrated development environment (IDE) or view them in a web browser.

# AWS CloudHSM KeyStore Java class for Client SDK 5
<a name="alternative-keystore_5"></a>

The AWS CloudHSM `KeyStore` class provides a special-purpose PKCS12 key store. This key store can store certificates along with your key data and correlate them to key data stored on AWS CloudHSM. The AWS CloudHSM `KeyStore` class implements the `KeyStore` Service Provider Interface (SPI) of the Java Cryptography Extension (JCE). For more information about using `KeyStore`, see [Class KeyStore](https://devdocs.io/openjdk~8/java/security/keystore).

**Note**  
Because certificates are public information, and to maximize storage capacity for cryptographic keys, AWS CloudHSM does not support storing certificates on HSMs.

## Choose the appropriate key store for AWS CloudHSM Client SDK 5
<a name="choosing_keystore_5"></a>

The AWS CloudHSM Java Cryptographic Extension (JCE) provider offers a special-purpose AWS CloudHSM KeyStore. The AWS CloudHSM `KeyStore` class supports offloading key operations to the HSM, local storage of certificates and certificate-based operations.

Load the special-purpose CloudHSM KeyStore as follows:

```
KeyStore ks = KeyStore.getInstance("CloudHSM")
```

## Initialize the AWS CloudHSM KeyStore Client SDK 5
<a name="initialize_cloudhsm_keystore_5"></a>

Log into the AWS CloudHSM KeyStore the same way that you log into the JCE provider. You can use either environment variables or the system property file, and you should log in before you start using the CloudHSM KeyStore. For an example of logging into an HSM using the JCE provider, see [Login to an HSM](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/LoginRunner.java).

If desired, you can specify a password to encrypt the local PKCS12 file which holds key store data. When you create the AWS CloudHSM Keystore, you set the password and provide it when using the load, set and get methods.

Instantiate a new CloudHSM KeyStore object as follows:

```
ks.load(null, null);
```

Write keystore data to a file using the `store` method. From that point on, you can load the existing keystore using the `load` method with the source file and password as follows: 

```
ks.load(inputStream, password);
```

## Use AWS CloudHSM KeyStore or AWS CloudHSM Client SDK 5
<a name="using_cloudhsm_keystore_5"></a>

AWS CloudHSM KeyStore complies with the JCE [Class KeyStore](https://devdocs.io/openjdk~8/java/security/keystore) specification and provides the following functions.
+ `load`

  Loads the key store from the given input stream. If a password was set when saving the key store, this same password must be provided for the load to succeed. Set both parameters to null to initialize an new empty key store.

  ```
  KeyStore ks = KeyStore.getInstance("CloudHSM");
  ks.load(inputStream, password);
  ```
+ `aliases`

  Returns an enumeration of the alias names of all entries in the given key store instance. Results include objects stored locally in the PKCS12 file and objects resident on the HSM. 

  **Sample code:**

  ```
  KeyStore ks = KeyStore.getInstance("CloudHSM");
  for(Enumeration<String> entry = ks.aliases(); entry.hasMoreElements();) {    
      String label = entry.nextElement();    
      System.out.println(label);
  }
  ```
+ `containsalias`

  Returns true if the key store has access to at least one object with the specified alias. The key store checks objects stored locally in the PKCS12 file and objects resident on the HSM.
+ `deleteEntry`

  Deletes a certificate entry from the local PKCS12 file. Deleting key data stored in an HSM is not supported using the AWS CloudHSM KeyStore. You can delete keys using the `destroy` method of the [Destroyable](https://devdocs.io/openjdk~8/javax/security/auth/destroyable#destroy--) interface.

  ```
  ((Destroyable) key).destroy();
  ```
+ `getCertificate`

  Returns the certificate associated with an alias if available. If the alias does not exist or references an object which is not a certificate, the function returns NULL. 

  ```
  KeyStore ks = KeyStore.getInstance("CloudHSM");
  Certificate cert = ks.getCertificate(alias);
  ```
+ `getCertificateAlias`

  Returns the name (alias) of the first key store entry whose data matches the given certificate. 

  ```
  KeyStore ks = KeyStore.getInstance("CloudHSM");
  String alias = ks.getCertificateAlias(cert);
  ```
+ `getCertificateChain`

  Returns the certificate chain associated with the given alias. If the alias does not exist or references an object which is not a certificate, the function returns NULL. 
+ `getCreationDate`

  Returns the creation date of the entry identified by the given alias. If a creation date is not available, the function returns the date on which the certificate became valid.
+ `getKey`

  GetKey is passed to the HSM and returns a key object corresponding to the given label. As `getKey` directly queries the HSM, it can be used for any key on the HSM regardless of whether it was generated by the KeyStore. 

  ```
  Key key = ks.getKey(keyLabel, null);
  ```
+ `isCertificateEntry`

  Checks if the entry with the given alias represents a certificate entry. 
+ `isKeyEntry`

  Checks if the entry with the given alias represents a key entry. The action searches both the PKCS12 file and the HSM for the alias. 
+ `setCertificateEntry`

  Assigns the given certificate to the given alias. If the given alias is already being used to identify a key or certificate, a `KeyStoreException` is thrown. You can use JCE code to get the key object and then use the KeyStore `SetKeyEntry` method to associate the certificate to the key.
+ `setKeyEntry` with `byte[]` key

  **This API is currently unsupported with Client SDK 5.**
+ `setKeyEntry` with `Key` object

  Assigns the given key to the given alias and stores it inside the HSM. If the key does not already exist inside the HSM, it will be imported into the HSM as an extractable session key.

  If the `Key` object is of type `PrivateKey`, it must be accompanied by a corresponding certificate chain. 

  If the alias already exists, the `SetKeyEntry` call throws a `KeyStoreException` and prevents the key from being overwritten. If the key must be overwritten, use KMU or JCE for that purpose. 
+ `engineSize`

  Returns the number of entries in the keystore.
+ `store`

  Stores the key store to the given output stream as a PKCS12 file and secures it with the given password. In addition, it persists all loaded keys (which are set using `setKey` calls).

# Advanced configurations for AWS CloudHSM JCE for Client SDK 5
<a name="java-lib-configs"></a>

The AWS CloudHSM JCE provider includes the following advanced configurations, which are not part of the general configurations most customers utilize.
+ [Connecting to multiple clusters](java-lib-configs-multi.md)
+ [Key extraction using JCE](java-lib-configs-getencoded.md)
+ [Retry configuration for JCE](java-lib-configs-retry.md)

# Connecting to multiple AWS CloudHSM clusters with the JCE provider
<a name="java-lib-configs-multi"></a>

This configuration allows a single client instance to communicate to multiple AWS CloudHSM clusters. Compared to having a single instance only communicate with a single cluster, this can be a cost-savings feature for some use cases. The `CloudHsmProvider` class is AWS CloudHSM's implementation of [Java Security's Provider class](https://docs.oracle.com/javase/8/docs/api/java/security/Provider.html). Each instance of this class represents a connection to your entire AWS CloudHSM cluster. You instantiate this class and add it to Java Security provider's list so that you can interact with it using standard JCE classes.

The following example instantiates this class and adds it to Java Security provider’s list:

```
if (Security.getProvider(CloudHsmProvider.PROVIDER_NAME) == null) {
    Security.addProvider(new CloudHsmProvider());
}
```

`CloudHsmProvider` can be configured in two ways:

1. Configure with file (default configuration)

1. Configure using code

The following topics describe these configurations, and how to connect to multiple clusters.

**Topics**
+ [Configure the AWS CloudHSM `CloudHsmProvider` class with a file (Default configuration)](java-lib-configs-default.md)
+ [Configure the AWS CloudHSM `CloudHsmProvider` class using code](java-lib-configs-using-code.md)
+ [Connect to multiple AWS CloudHSM clusters](java-lib-connecting-to-multiclusters.md)

# Configure the AWS CloudHSM `CloudHsmProvider` class with a file (Default configuration)
<a name="java-lib-configs-default"></a>

The default way to configure the AWS CloudHSM `CloudHsmProvider` class is with a file.

When you instantiate `CloudHsmProvider` using default constructor, by default it will look for configuration file in `/opt/cloudhsm/etc/cloudhsm-jce.cfg` path in Linux. This configuration file can be configured using the `configure-jce`. 

An object created using the default constructor will use the default CloudHSM provider name `CloudHSM`. The provider name is useful to interact with JCE to let it know which provider to use for various operation. An example to use CloudHSM provider name for Cipher operation is as below:

```
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "CloudHSM");
```

# Configure the AWS CloudHSM `CloudHsmProvider` class using code
<a name="java-lib-configs-using-code"></a>

As of Client SDK version 5.8.0, you can also configure the AWS CloudHSM `CloudHsmProvider` class using Java code. The way to do this is using an object of `CloudHsmProviderConfig` class. You can build this object using `CloudHsmProviderConfigBuilder`. 

`CloudHsmProvider` has another constructor which takes the `CloudHsmProviderConfig` object, as the following sample shows.

**Example**  

```
CloudHsmProviderConfig config = CloudHsmProviderConfig.builder()  
                                    .withCluster(  
                                        CloudHsmCluster.builder()  
                                            .withHsmCAFilePath(hsmCAFilePath)
                                            .withClusterUniqueIdentifier("CloudHsmCluster1")
        .withServer(CloudHsmServer.builder().withHostIP(hostName).build())  
                        .build())  
        .build();
CloudHsmProvider provider = new CloudHsmProvider(config);
```

In this example, the name of the JCE provider is `CloudHsmCluster1`. This is the name that application can then use to interact with JCE:

**Example**  

```
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "CloudHsmCluster1");
```

Alternatively, applications can also use the provider object created above to let JCE know to use that provider for the operation:

```
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", provider);
```

If a unique identifier is not specified with the `withClusterUniqueIdentifier` method, a randomly generated provider name is created for you. To get this randomly generated identifier, applications can call `provider.getName()` to get the identifier.

# Connect to multiple AWS CloudHSM clusters
<a name="java-lib-connecting-to-multiclusters"></a>

Each `CloudHsmProvider` represents a connection to your AWS CloudHSM Cluster. If you want to talk to another cluster from the same application, you can create another object of `CloudHsmProvider` with configurations for your other cluster and you can interact with this other cluster either using the provider object or using the provider name, as shown in the following example.

**Example**  

```
CloudHsmProviderConfig config = CloudHsmProviderConfig.builder()  
                                    .withCluster(  
                                        CloudHsmCluster.builder()  
                                            .withHsmCAFilePath(hsmCAFilePath)
                                            .withClusterUniqueIdentifier("CloudHsmCluster1")
        .withServer(CloudHsmServer.builder().withHostIP(hostName).build())  
                        .build())  
        .build();
CloudHsmProvider provider1 = new CloudHsmProvider(config);

if (Security.getProvider(provider1.getName()) == null) {
    Security.addProvider(provider1);
}

CloudHsmProviderConfig config2 = CloudHsmProviderConfig.builder()  
                                    .withCluster(  
                                        CloudHsmCluster.builder()  
                                            .withHsmCAFilePath(hsmCAFilePath2)
                                            .withClusterUniqueIdentifier("CloudHsmCluster2")
        .withServer(CloudHsmServer.builder().withHostIP(hostName2).build())  
                        .build())  
        .build();
CloudHsmProvider provider2 = new CloudHsmProvider(config2);

if (Security.getProvider(provider2.getName()) == null) {
    Security.addProvider(provider2);
}
```

Once you have configured both the providers (both the clusters) above, you can interact with them either using the provider object or using the provider name. 

Expanding upon this example that shows how to talk to `cluster1`, you could use the following sample for a AES/GCM/NoPadding operation:

```
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", provider1);
```

And in the same application to do "AES" Key generation on the second cluster using the provider name, you could also use the following sample:

```
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", provider2.getName());
```

# Key extraction using JCE for AWS CloudHSM
<a name="java-lib-configs-getencoded"></a>

The Java Cryptography Extension (JCE) uses an architecture that allows different cryptography implementations to be plugged in. AWS CloudHSM ships one such JCE provider that offloads cryptographic operations to the HSM. For most other JCE providers to work with keys stored in AWS CloudHSM, they must extract the key bytes from your HSMs in clear text into your machine’s memory for their use. HSMs typically only allow keys to be extracted as wrapped objects, not clear text. However, to support inter-provider integration use cases, AWS CloudHSM allows an opt-in configuration option to enable extraction of the key bytes in the clear.

**Important**  
JCE offloads operations to AWS CloudHSM whenever the AWS CloudHSM provider is specified or an AWS CloudHSM key object is used. You do not need to extract keys in clear if you expect your operation to happen inside the HSM. Key extraction in clear text is only needed when your application cannot use secure mechanisms such as wrapping and unwrapping a key due to restrictions from a third party library or JCE provider. 

The AWS CloudHSM JCE Provider allows extraction of **public keys** to work with external JCE providers by default. The following methods are always allowed:


| Class | Method | Format (getEncoded) | 
| --- | --- | --- | 
| EcPublicKey | getEncoded() | X.509 | 
|  | getW() | N/A | 
| RSAPublicKey | getEncoded() | X.509 | 
|  | getPublicExponent() | N/A | 
| CloudHsmRsaPrivateCrtKey | getPublicExponent() | N/A | 

The AWS CloudHSM JCE Provider doesn’t allow extraction of key bytes in clear for the **private** or **secret** keys by default. If your use case requires it, you can enable extraction of key bytes in clear for **private** or **secret** keys under the following conditions:

1. The `EXTRACTABLE` attribute for private and secret keys is set to **true**.
   + By default, the `EXTRACTABLE` attribute for private and secret keys is set to **true**. `EXTRACTABLE` keys are keys that are permitted to be exported out of the HSM. For more information see Supported Java attributes for [Client SDK 5](java-lib-attributes_5.md).

1. The `WRAP_WITH_TRUSTED` attribute for the private and secret keys is set to **false**.
   + `getEncoded`, `getPrivateExponent`, and `getS` cannot be used with private keys that cannot be exported in clear. `WRAP_WITH_TRUSTED` doesn't allow your private keys to exported out of the HSM in clear. For more information see [Using trusted keys to control key unwraps](manage-keys-using-trusted-keys.md).

# Allow the JCE provider to extract private key secrets out of AWS CloudHSM
<a name="get-encoded-take-out-private-keys"></a>

Use the following steps to allow AWS CloudHSM JCE provider to extract your private key secrets.

**Important**  
This configuration change allows extraction of all `EXTRACTABLE` key bytes in clear from your HSM cluster. For better security, you should consider using [key wrapping methods](java-lib-supported_5.md) to extract the key out of the HSM securely. This prevents unintentional extraction of your key bytes from the HSM. 

1. Use the following commands to enable your **private** or **secret** keys to be extracted in JCE:

------
#### [ Linux ]

   ```
   $ /opt/cloudhsm/bin/configure-jce --enable-clear-key-extraction-in-software
   ```

------
#### [ Windows ]

   ```
   PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\configure-jce.exe" --enable-clear-key-extraction-in-software
   ```

------

1. Once you enable your clear key extraction, the following methods are enabled for extracting private keys into memory.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/get-encoded-take-out-private-keys.html)

If you want restore the default behavior and not allow JCE to export keys in clear, run the following command:

------
#### [ Linux ]

```
$ /opt/cloudhsm/bin/configure-jce --disable-clear-key-extraction-in-software
```

------
#### [ Windows ]

```
PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\configure-jce.exe" --disable-clear-key-extraction-in-software
```

------

# Retry commands for JCE for AWS CloudHSM
<a name="java-lib-configs-retry"></a>

AWS CloudHSM Client SDK 5.8.0 and later have a built-in automatic retry strategy which will retry HSM-throttled operations from the client side. When an HSM throttles operations because it is too busy performing previous operations and cannot take more requests, client SDKs will attempt to retry throttled operations up to 3 times while exponentially backing off. This automatic retry strategy can be set to one of two modes: **off** and **standard**.
+ **off**: The Client SDK will not perform any retry strategy for any throttled operations by the HSM.
+ **standard**: This is the default mode for Client SDK 5.8.0 and later. In this mode, client SDKs will automatically retry throttled operations by exponentially backing off.

For more information, see [HSM throttling](troubleshoot-hsm-throttling.md).

## Set retry commands to off mode
<a name="w2aac25c21c25c25c15b9"></a>

------
#### [ Linux ]

**To set retry commands to **off** for Client SDK 5 on Linux**
+ You can use the following command to set retry configuration to **off** mode:

  ```
  $ sudo /opt/cloudhsm/bin/configure-jce --default-retry-mode off
  ```

------
#### [ Windows ]

**To set retry commands to **off** for Client SDK 5 on Windows**
+ You can use the following command to set retry configuration to **off** mode:

  ```
  PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\configure-jce.exe" --default-retry-mode off
  ```

------

