

# Keys in AWS CloudHSM
<a name="manage-keys"></a>

Before you can use your AWS CloudHSM cluster for cryptoprocessing, you must create [users](manage-hsm-users.md) and keys on the hardware security modules (HSM) in your cluster. 

In AWS CloudHSM, use any of the following to manage keys on the HSMs in your cluster: 
+ PKCS \$111 library
+ JCE provider
+ CNG and KSP providers
+ CloudHSM CLI

Before you can manage keys, you must log in to the HSM with the user name and password of a crypto user (CU). Only a CU can create a key. The CU who creates a key owns and manages that key.

See the following topics for more information about managing keys in AWS CloudHSM.

**Topics**
+ [Key sync and durability](manage-key-sync.md)
+ [AES key wrapping](manage-aes-key-wrapping.md)
+ [Trusted keys](manage-keys-using-trusted-keys.md)
+ [Key management with CloudHSM CLI](manage-keys-chsm-cli.md)
+ [Key management with KMU](manage-keys-kmu-cmu.md)

# Key synchronization and durability settings in AWS CloudHSM
<a name="manage-key-sync"></a>

AWS CloudHSM synchronizes every token key you create. Key synchronization is mostly an automatic process, but you can use a minimum of two hardware security modules (HSM) in your cluster to make keys more durable. This topic describes key synchronization settings, common issues customers face working with keys on a cluster, and strategies for making keys more durable.

This topic describes key synchronization settings in AWS CloudHSM, common issues customers face working with keys on a cluster, and strategies for making keys more durable.

**Topics**
+ [Concepts](concepts-key-sync.md)
+ [Understanding key synchronization](understand-key-sync.md)
+ [Change client key durability settings](working-client-sync.md)
+ [Synchronizing keys across cloned clusters](cli-sync.md)

# AWS CloudHSM key concepts
<a name="concepts-key-sync"></a>

The following are concepts to be aware of when working with keys in AWS CloudHSM.

**Token keys**  
Persistent keys that you create during key generate, import or unwrap operations. AWS CloudHSM synchronizes token keys across a cluster.

**Session keys**  
Ephemeral keys that exist only on one hardware security module (HSM) in the cluster. AWS CloudHSM does *not* synchronize session keys across a cluster.

**Client-side key synchronization**  
A client-side process that clones token keys you create during key generate, import or unwrap operations. You can make token keys more durable by running a cluster with a minimum of two HSMs.

**Server-side key synchronization**  
Periodically clones keys to every HSM in the cluster. Requires no management.

**Client key durability settings**  
Settings you configure on the client that impact key durability. These settings work differently in Client SDK 5 and Client SDK 3.   
+ In Client SDK 5, use this setting to run a single HSM cluster. 
+ In Client SDK 3, use this setting to specify the number of HSMs required for key creation operations to succeed.

# Understanding AWS CloudHSM key synchronization
<a name="understand-key-sync"></a>

AWS CloudHSM uses key synchronization to clone token keys across all the hardware security modules (HSM) in a cluster. You create token keys as persistent keys during key generation, import, or unwrap operations. To distribute these keys across the cluster, CloudHSM offers both client-side and server-side key synchronization.

![\[Key synchronization diagram showing client-side and server-side sync for CloudHSM cluster.\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/key-synch.png)


The goal with key synchronization—both server side and client side—is to distribute new keys across the cluster as quickly as possible after you create them. This is important because the subsequent calls you make to use new keys can get routed to any available HSM in the cluster. If the call you make routes to an HSM without the key, then the call fails. You can mitigate these type failures by specifying that your applications retry subsequent calls made after key creation operations. The time required to synchronize can vary, depending on the workload of your cluster and other intangibles. Use CloudWatch metrics to determine the timing your application should employ in this type situation. For more information, see [CloudWatch Metrics](hsm-metrics-cw.md).

The challenge with key synchronization in a cloud environment is key durability. You create keys on a single HSM and often begin using those keys immediately. If the HSM on which you create keys should fail before the keys have been cloned to another HSM in the cluster, you lose the keys *and* access to anything encrypted by the keys. To mitigate this risk, we offer *client-side synchronization*. Client side synchronization is a client-side process that clones the keys you create during key generate, import, or unwrap operations. Cloning keys as you create them makes keys more durable. Of course, you can't clone keys in a cluster with a single HSM. To make keys more durable, we also recommend you configure your cluster to use a minimum of two HSMs. With client-side synchronization and a cluster with two HSMs, you can meet the challenge of key durability in a cloud environment.

# Change AWS CloudHSM client key durability settings
<a name="working-client-sync"></a>

Key synchronization is mostly an automatic process, but you can manage client-side key durability settings. Client-side key durability settings works differently in Client SDK 5 and Client SDK 3. 
+ In Client SDK 5, we introduce the concept of *key availability quorums* which requires you to run clusters with a minimum of two HSMs. You can use client-side key durability settings to opt out of the two HSM requirement. For more information about quorums, see [AWS CloudHSM key concepts](concepts-key-sync.md).
+ In Client SDK 3, you use client-side key durability settings to specify the number of HSMs on which key creation must succeed for the overall operation to be deemed a success. 

## Client SDK 5 client key durability settings
<a name="client-sync-sdk8"></a>

In Client SDK 5, key synchronization is a fully automatic process. With key availability quorum, newly created keys must exist on two HSMs in the cluster before your application can use the key. To use key availability quorum, your cluster must have a minimum of two HSMs.

If your cluster configuration doesn’t meet the key durability requirements, any attempt to create or use a token key will fail with the following error message in the logs:

```
Key <key handle> does not meet the availability requirements - The key must be available on at least 2 HSMs before being used.
```

You can use client configuration settings to opt out of key availability quorum. You might want to opt out to run a cluster with a single HSM, for example. 

### Client SDK 5 concepts
<a name="client-sync-8concept"></a>

**Key Availability Quorum**  
AWS CloudHSM specifies the number of HSMs in a cluster on which keys must exist before your application can use the key. Requires clusters with a minimum of two HSMs.

### Managing client key durability settings
<a name="setting-file-sdk8"></a>

To manage client key durability settings, you must use the configure tool for Client SDK 5. 

------
#### [ PKCS \$111 library ]

**To disable client key durability for Client SDK 5 on Linux**
+  Use the configure tool to disable client key durability settings. 

  ```
  $ sudo /opt/cloudhsm/bin/configure-pkcs11 --disable-key-availability-check
  ```

**To disable client key durability for Client SDK 5 on Windows**
+  Use the configure tool to disable client key durability settings. 

  ```
  PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\configure-pkcs11.exe" --disable-key-availability-check
  ```

------
#### [ OpenSSL Dynamic Engine ]

**To disable client key durability for Client SDK 5 on Linux**
+  Use the configure tool to disable client key durability settings. 

  ```
  $ sudo /opt/cloudhsm/bin/configure-dyn --disable-key-availability-check
  ```

------
#### [ OpenSSL Dynamic Engine Provider ]

**To disable client key durability for Client SDK 5 on Linux**
+  Use the configure tool to disable client key durability settings. 

  ```
  $ sudo /opt/cloudhsm/bin/configure-openssl-provider --disable-key-availability-check
  ```

------
#### [ Key Storage Provider (KSP) ]

**To disable client key durability for Client SDK 5 on Windows**
+  Use the configure tool to disable client key durability settings. 

  ```
  PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\configure-ksp.exe" --disable-key-availability-check
  ```

------
#### [ JCE provider ]

**To disable client key durability for Client SDK 5 on Linux**
+  Use the configure tool to disable client key durability settings. 

  ```
  $ sudo /opt/cloudhsm/bin/configure-jce --disable-key-availability-check
  ```

**To disable client key durability for Client SDK 5 on Windows**
+  Use the configure tool to disable client key durability settings. 

  ```
  PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\configure-jce.exe" --disable-key-availability-check
  ```

------
#### [ CloudHSM CLI ]

**To disable client key durability for Client SDK 5 on Linux**
+  Use the configure tool to disable client key durability settings. 

  ```
  $ sudo /opt/cloudhsm/bin/configure-cli --disable-key-availability-check
  ```

**To disable client key durability for Client SDK 5 on Windows**
+  Use the configure tool to disable client key durability settings. 

  ```
  PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\configure-cli.exe" --disable-key-availability-check
  ```

------

## Client SDK 3 client key durability settings
<a name="client-sync-sdk3"></a>

In Client SDK 3, key synchronization is mostly an automatic process, but you can use the client key durability settings to make keys more durable. You specify the number of HSMs on which key creation must succeed for the overall operation to be deemed a success. Client-side synchronization always makes a best-effort attempt to clone keys to every HSM in the cluster no matter what setting you choose. Your setting enforces key creation on the number of HSMs you specify. If you specify a value and the system cannot replicate the key to that number of HSMs, then the system automatically cleans up any unwanted key material and you can try again.

**Important**  
If you don’t set client key durability settings (or if you use the default value of 1), your keys are vulnerable to loss. If your current HSM should fail before the server-side service has cloned that key to another HSM, you lose the key material. 

To maximize key durability, consider specifying at least two HSMs for client-side synchronization. Remember that no matter how many HSMs you specify, the workload on your cluster remains the same. Client-side synchronization always makes a best-effort attempt to clone keys to every HSM in the cluster. 

**Recommendations**
+ **Minimum**: Two HSMs per cluster
+ **Maximum**: One fewer than the total number of HSMs in your cluster

If client-side synchronization fails, the client service cleans up any unwanted keys that may have been created and are now unwanted. This clean up is a best-effort response that may not always work. If cleanup fails, you may have to delete unwanted key material. For more information, see [Key Synchronization Failures](ts-client-sync-fail.md).

### Setting up the configuration file for client key durability
<a name="setting-file"></a>

To specify client key durability settings, you must edit `cloudhsm_client.cfg`. 

**To edit the client configuration file**

1. Open `cloudhsm_client.cfg`.

   **Linux**:

   ```
   /opt/cloudhsm/etc/cloudhsm_client.cfg
   ```

   **Windows**:

   ```
   C:\ProgramData\Amazon\CloudHSM\data\cloudhsm_client.cfg
   ```

1. In the `client` node of the file, add `create_object_minimum_nodes` and specify a value for the minimum number of HSMs on which AWS CloudHSM must successfully create keys for key creation operations to succeed.

   ```
   "create_object_minimum_nodes" : 2
   ```
**Note**  
The key\$1mgmt\$1util (KMU) command-line tool has an additional setting for client key durability. For more information, see [KMU and client-side synchronization](#kmu-sync)

#### Configuration reference
<a name="client-side-ref"></a>

These are the client-side synchronization properties, shown in an excerpt of the `cloudhsm_client.cfg`:

```
{
    "client": {
        "create_object_minimum_nodes" : 2,
        ...
    },
    
    ...
}
```

**create\$1object\$1minimum\$1nodes**  
Specifies the minimum number of HSMs required to deem key generation, key import, or key unwrap operations a success. If set, the default is 1. This means that for every key create operation, the client-side service attempts to create keys on every HSM in the cluster, but to return a success, only needs to create a *single key* on one HSM in the cluster. 

### KMU and client-side synchronization
<a name="kmu-sync"></a>

If you create keys with the key\$1mgmt\$1util (KMU) command-line tool, you use an optional command line parameter (`-min_srv`) to *limit* the number of HSMs on which to clone keys. If you specify the command-line parameter *and* a value in the configuration file, AWS CloudHSM honors the LARGER of the two values.

 For more information, see the following topics:
+ [genDSAKeyPair](key_mgmt_util-genDSAKeyPair.md)
+ [genECCKeyPair](key_mgmt_util-genECCKeyPair.md)
+ [genRSAKeyPair](key_mgmt_util-genRSAKeyPair.md)
+ [genSymKey](key_mgmt_util-genSymKey.md)
+ [importPrivateKey](key_mgmt_util-importPrivateKey.md)
+ [importPubKey](key_mgmt_util-importPubKey.md)
+ [imSymKey](key_mgmt_util-imSymKey.md)
+ [insertMaskedObject](key_mgmt_util-insertMaskedObject.md)
+ [unWrapKey](key_mgmt_util-unwrapKey.md)

# Synchronizing keys across cloned AWS CloudHSM clusters
<a name="cli-sync"></a>

Client-side and server-side synchronization are only for synchronizing keys within the *same* AWS CloudHSM cluster. If you copy a backup of a cluster to another region, use the [key replicate](cloudhsm_cli-key-replicate.md) command to replicate a key between two clusters. You might use cloned clusters for cross-region redundancy or to simplify your disaster recovery process. If you haven't installed CloudHSM CLI, see the instructions in [Getting started with AWS CloudHSM Command Line Interface (CLI)](cloudhsm_cli-getting-started.md).

# AES key wrapping in AWS CloudHSM
<a name="manage-aes-key-wrapping"></a>

This topic describes the options for AES key wrapping in AWS CloudHSM. AES key wrapping uses an AES key (the wrapping key) to wrap another key of any type (the target key). You use key wrapping to protect stored keys or transmit keys over insecure networks.

**Topics**
+ [Supported algorithms](#supported-types)
+ [Using AES key wrap in AWS CloudHSM](#use-aes-key-wrap)

## Supported algorithms
<a name="supported-types"></a>

AWS CloudHSM offers three options for AES key wrapping, each based on how the target key is padded before being wrapped. Padding is done automatically, in accordance with the algorithm you use, when you call key wrap. The following table lists the supported algorithms and associated details to help you choose an appropriate wrapping mechanism for your application.


| AES Key Wrap Algorithm | Specification | Supported Target Key Types | Padding Scheme | AWS CloudHSM Client Availability  | 
| --- | --- | --- | --- | --- | 
| AES Key Wrap with Zero Padding  | [RFC 5649](https://tools.ietf.org/html/rfc5649) and [SP 800–38F](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf) | All | Adds zeros after key bits, if necessary, to block align | SDK 3.1 and later | 
| AES Key Wrap with No Padding | [RFC 3394](https://tools.ietf.org/html/rfc3394) and [SP 800–38F](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf) | Block-aligned keys such as AES and 3DES  | None | SDK 3.1 and later | 
| AES Key Wrap with PKCS \$15 Padding | None | All |  At least 8 bytes are added as per PKCS \$15 padding scheme to block align   | All | 

To learn how to use the AES key wrap algorithms from the preceding table in your application, see [Using AES Key Wrap in AWS CloudHSM.](#use-aes-key-wrap)

### Understanding initialization vectors in AES key wrap
<a name="understand-padding-iv"></a>

Prior to wrapping, CloudHSM appends an initialization vector (IV) to the target key for data integrity. Each key wrap algorithm has specific restrictions on what type of IV is allowed. To set the IV in AWS CloudHSM, you have two options:
+ Implicit: set the IV to NULL and CloudHSM uses the default value for that algorithm for wrap and unwrap operations (recommended)
+ Explicit: set the IV by passing the default IV value to the key wrap function 

**Important**  
You must understand what IV you are using in your application. To unwrap the key, you must provide the same IV that you used to wrap the key. If you use an implicit IV to wrap, then use an implicit IV to unwrap. With an implicit IV, CloudHSM will use the default value to unwrap. 

The following table describes permitted values for IVs, which the wrapping algorithm specifies. 


****  

| AES Key Wrap Algorithm | Implicit IV | Explicit IV | 
| --- | --- | --- | 
| AES Key Wrap with Zero Padding  | Required Default value: (IV calculated internally based on specification) | Not allowed | 
| AES Key Wrap with No Padding | Allowed (recommended) Default value: `0xA6A6A6A6A6A6A6A6` | Allowed Only this value accepted: `0xA6A6A6A6A6A6A6A6` | 
| AES Key Wrap with PKCS \$15 Padding | Allowed (recommended) Default value: `0xA6A6A6A6A6A6A6A6` | Allowed Only this value accepted: `0xA6A6A6A6A6A6A6A6` | 

## Using AES key wrap in AWS CloudHSM
<a name="use-aes-key-wrap"></a>

 You wrap and unwrap keys as follows:
+ In the [PKCS \$111 library](pkcs11-library.md), select the appropriate mechanism for the `C_WrapKey` and `C_UnWrapKey` functions as shown in the following table.
+ In the [JCE provider](java-library.md), select the appropriate algorithm, mode and padding combination, implementing cipher methods `Cipher.WRAP_MODE` and `Cipher.UNWRAP_MODE` as shown in the following table.
+ In the [CloudHSM CLI](cloudhsm_cli.md), choose the appropriate algorithm from the list of supported [The key wrap command in CloudHSM CLI](cloudhsm_cli-key-wrap.md) and [The key unwrap command in CloudHSM CLI](cloudhsm_cli-key-unwrap.md) algorithms as shown in the following table.
+ In [key\$1mgmt\$1util (KMU)](key_mgmt_util.md), use commands [Export an AWS CloudHSM key using KMU](key_mgmt_util-wrapKey.md) and [Unwrap an AWS CloudHSM key using KMU](key_mgmt_util-unwrapKey.md) with appropriate m values as shown in the following table. 


****  

| AES Key Wrap Algorithm | PKCS \$111 Mechanism | Java Method | CloudHSM CLI Sub Command | Key Management Utility (KMU) Argument | 
| --- | --- | --- | --- | --- | 
| AES Key Wrap with Zero Padding  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/manage-aes-key-wrapping.html)  | AESWrap/ECB/ZeroPadding | aes-zero-pad | m = 6 | 
| AES Key Wrap with No Padding |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/manage-aes-key-wrapping.html)  | AESWrap/ECB/NoPadding | aes-no-pad | m = 5 | 
| AES Key Wrap with PKCS \$15 Padding  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/manage-aes-key-wrapping.html)  | AESWrap/ECB/PKCS5Padding | aes-pkcs5-pad | m = 4 | 

# Using trusted keys in AWS CloudHSM
<a name="manage-keys-using-trusted-keys"></a>

AWS CloudHSM supports trusted key wrapping to protect data keys from insider threats. This topic describes how to create trusted keys to secure data.

**Topics**
+ [Understanding trusted keys](understand-trusted-key-wraps.md)
+ [Trusted key attributes](key_attribute_background.md)
+ [How to use trusted keys to wrap data keys](wrap_keys_using_trusted.md)
+ [How to unwrap a data key with a trusted key](unwrap_keys_using_trusted.md)

# Understanding trusted keys in AWS CloudHSM
<a name="understand-trusted-key-wraps"></a>

A *trusted key* is a key that is used to wrap other keys and that admins and cryptographic officers (COs) specifically identify as trusted using the attribute `CKA_TRUSTED`. Additionally, admins and cryptographic officers (COs) use `CKA_UNWRAP_TEMPLATE` and related attributes to specify what actions data keys can do once they are unwrapped by a trusted key. Data keys that are unwrapped by the trusted key must also contain these attributes for the unwrap operation to succeed, which helps ensure that unwrapped data keys are only permitted for the use you intend.

Use the attribute `CKA_WRAP_WITH_TRUSTED` to identify all of the data keys you want to wrap with trusted keys. Doing this allows you to restrict data keys so applications can only use trusted keys to unwrap them. Once you set this attribute on the data keys, the attribute becomes read-only and you cannot change it. With these attributes in place, applications can only unwrap your data keys with the keys you trust, and unwraps always result in data keys with attributes that limit how these keys can be used.

# Trusted key attributes in AWS CloudHSM
<a name="key_attribute_background"></a>

The following attributes allow you to mark an AWS CloudHSM key as trusted, specify a data key can only be wrapped and unwrapped with a trusted key, and control what a data key can do after it is unwrapped:
+ `CKA_TRUSTED`: Apply this attribute (in addition to `CKA_UNWRAP_TEMPLATE`) to the key that will wrap data keys to specify that an admin or crypto officer (CO) has done the necessary diligence and trusts this key. Only an admin or CO can set `CKA_TRUSTED`. The crypto user (CU) owns the key, but only a CO can set its `CKA_TRUSTED` attribute.
+ `CKA_WRAP_WITH_TRUSTED`: Apply this attribute to an exportable data key to specify that you can only wrap this key with keys marked as `CKA_TRUSTED`. Once you set `CKA_WRAP_WITH_TRUSTED` to true, the attribute becomes read-only and you cannot change or remove the attribute.
+ `CKA_UNWRAP_TEMPLATE`: Apply this attribute to the wrapping key (in addition to `CKA_TRUSTED`) to specify which attribute names and values the service must automatically apply to data keys that the service unwraps. When an application submits a key for unwrapping, the application can also provide its own unwrap template. If you specify an unwrap template and the application provides its own unwrap template, the HSM uses both templates to apply attribute names and values to the key. However, if a value in the `CKA_UNWRAP_TEMPLATE` for the wrapping key conflicts with an attribute provided by the application during the unwrap request, then the unwrap request fails. 

For more information about attributes, refer to the following topics:
+ [PKCS \$111 key attributes](pkcs11-attributes.md)
+ [JCE key attributes](java-lib-attributes_5.md)
+ [CloudHSM CLI key attributes](cloudhsm_cli-key-attributes.md)

# How to use trusted keys to wrap data keys in AWS CloudHSM
<a name="wrap_keys_using_trusted"></a>

To use a trusted key to wrap a data key in AWS CloudHSM, you must complete three basic steps:

1. For the data key you plan to wrap with a trusted key, set its `CKA_WRAP_WITH_TRUSTED` attribute to true.

1. For the trusted key you plan to wrap the data key with, set its `CKA_TRUSTED` attribute to true.

1. Use the trusted key to wrap the data key.

## Step 1: Set the data key's `CKA_WRAP_WITH_TRUSTED` to true
<a name="w2aac15c19c11b7"></a>

For the data key you want to wrap, choose one of the following options to set the key’s `CKA_WRAP_WITH_TRUSTED` attribute to true. Doing this restricts the data key so applications can only use trusted keys to wrap it.

### Option 1: If generating a new key, set `CKA_WRAP_WITH_TRUSTED` to true
<a name="w2aac15c19c11b7b5"></a>

Generate a key using [PKCS \$111](pkcs11-library.md), [JCE](java-library.md), or [CloudHSM CLI](cloudhsm_cli.md). See the following examples for more details.

------
#### [ PKCS \$111 ]

To generate a key with PKCS \$111, you need to set the key's `CKA_WRAP_WITH_TRUSTED` attribute to true. As shown in the following example, do this by including this attribute in the key’s `CK_ATTRIBUTE template` and then setting the attribute to true:

```
CK_BYTE_PTR label = "test_key";
CK_ATTRIBUTE template[] = {
        {CKA_WRAP_WITH_TRUSTED, &true_val,         sizeof(CK_BBOOL)},
        {CKA_LABEL,             label,             strlen(label)},
        ...
};
```

For more information, see [our public samples demonstrating key generation with PKCS \$111](https://github.com/aws-samples/aws-cloudhsm-pkcs11-examples/tree/master/src/generate).

------
#### [ JCE ]

To generate a key with JCE, you need to set the key's `WRAP_WITH_TRUSTED` attribute to true. As shown in the following example, do this by including this attribute in the key’s `KeyAttributesMap` and then setting the attribute to true:

```
final String label = "test_key";
final KeyAttributesMap keySpec = new KeyAttributesMap();
keySpec.put(KeyAttribute.WRAP_WITH_TRUSTED, true);
keySpec.put(KeyAttribute.LABEL, label);
...
```

For more information, see [our public samples demonstrating key generation with JCE](https://docs.aws.amazon.com/cloudhsm/latest/userguide/java-samples.html#java-samples-code_5).

------
#### [ CloudHSM CLI ]

To generate a key with CloudHSM CLI, you need to set the key's `wrap-with-trusted` attribute to true. Do this by including `wrap-with-trusted=true` in the appropriate argument for the key generation command:
+ For symmetric keys, add `wrap-with-trusted` to the `attributes` argument.
+ For public keys, add `wrap-with-trusted` to the `public-attributes` argument.
+ For private keys, add `wrap-with-trusted` to the `private-attributes` argument.

For more information on key pair generation, see [The generate-asymmetric-pair category in CloudHSM CLI](cloudhsm_cli-key-generate-asymmetric-pair.md).

For more information on symmetric key generation, see [The generate-symmetric category in CloudHSM CLI](cloudhsm_cli-key-generate-symmetric.md).

------

### Option 2: If using an existing key, use CloudHSM CLI to set its `CKA_WRAP_WITH_TRUSTED` to true
<a name="w2aac15c19c11b7b7"></a>

To set an existing key's `CKA_WRAP_WITH_TRUSTED` attribute to true, follow these steps:

1. Use the [Log in to an HSM using CloudHSM CLI](cloudhsm_cli-login.md) command to log in as a crypto user (CU).

1. Use the [Set the attributes of keys with CloudHSM CLI](cloudhsm_cli-key-set-attribute.md) command to set the key's `wrap-with-trusted` attribute to true.

   ```
   aws-cloudhsm > key set-attribute --filter attr.label=test_key --name wrap-with-trusted --value true
   {
     "error_code": 0,
     "data": {
       "message": "Attribute set successfully"
     }
   }
   ```

## Step 2: Set the trusted key's `CKA_TRUSTED` to true
<a name="w2aac15c19c11b9"></a>

To make a key a trusted key, its `CKA_TRUSTED` attribute must be set to true. You can either use CloudHSM CLI or the CloudHSM Management Utility (CMU) to do this.
+ If using CloudHSM CLI to set a key's `CKA_TRUSTED` attribute, see [Mark a key as trusted using CloudHSM CLI](manage-keys-cloudhsm-cli-trusted.md).
+ If using the CMU to set a key's `CKA_TRUSTED` attribute, see [How to mark a key as trusted with the AWS CloudHSM Management Utility](cloudhsm_using_trusted_keys_control_key_wrap.md).

## Step 3. Use the trusted key to wrap the data key
<a name="w2aac15c19c11c11"></a>

To wrap the data key referenced in Step 1 with the trusted key you set in Step 2, refer to the following links for code samples. Each demonstrates how to wrap keys.
+ [AWS CloudHSM PKCS \$111 examples](https://github.com/aws-samples/aws-cloudhsm-pkcs11-examples/tree/master/src/wrapping)
+ [AWS CloudHSM JCE examples](https://github.com/aws-samples/aws-cloudhsm-jce-examples/tree/sdk5/src/main/java/com/amazonaws/cloudhsm/examples)

# How to unwrap a data key with a trusted key for AWS CloudHSM
<a name="unwrap_keys_using_trusted"></a>

To unwrap a data key in AWS CloudHSM, you need a trusted key that has `CKA_UNWRAP` set to true. To be such a key, it must also meet the following criteria:
+ The key’s `CKA_TRUSTED` attribute must be set to true.
+ The key must use `CKA_UNWRAP_TEMPLATE` and related attributes to specify what actions data keys can perform once they are unwrapped. If, for example, you want an unwrapped key to be non-exportable, you set `CKA_EXPORTABLE = FALSE` as part of the `CKA_UNWRAP_TEMPLATE`.

**Note**  
`CKA_UNWRAP_TEMPLATE` is only available with PKCS \$111.

When an application submits a key to be unwrapped, the application can also provide its own unwrap template. If you specify an unwrap template and the application provides its own unwrap template, the HSM uses both templates to apply attribute names and values to the key. However, if during the unwrap request a value in the trusted key’s `CKA_UNWRAP_TEMPLATE` conflicts with an attribute provided by the application, the unwrap request fails. 

To see an example on unwrapping a data key with a trusted key, refer to [this PKCS \$111 example](https://github.com/aws-samples/aws-cloudhsm-pkcs11-examples/blob/master/src/wrapping/unwrap_with_template.c).

# Key management with CloudHSM CLI
<a name="manage-keys-chsm-cli"></a>

If using the [latest SDK version series](use-hsm.md), use [CloudHSM CLI](cloudhsm_cli.md) to manage the keys in your AWS CloudHSM cluster. For more details, see the topics below.
+ [Using trusted keys](manage-keys-cloudhsm-cli-trusted.md) describes how to use CloudHSM CLI to create trusted keys to secure data.
+ [Generating keys](manage-keys-cloudhsm-cli-generate.md) includes instructions on creating keys, including symmetric keys, RSA keys, and EC keys.
+ [Deleting keys](manage-keys-cloudhsm-cli-delete.md) describes how key owners delete keys.
+ [Sharing and unsharing keys](manage-keys-cloudhsm-cli-share.md) details how key owners share and unshare keys.
+ [Filtering keys](manage-keys-cloudhsm-cli-filtering.md) offers guidelines on how to use filters to find keys.
+ [Manage key quorum authentication (M of N) ](key-quorum-auth-chsm-cli.md) offers guidelines on how to setup and use quorum authentication with keys.

# Generate keys with CloudHSM CLI
<a name="manage-keys-cloudhsm-cli-generate"></a>

Before you can generate a key, you must start [CloudHSM CLI](cloudhsm_cli.md) and log in as a crypto user (CU). To generate keys on the HSM, use the command that corresponds to the type of key that you want to generate.

**Topics**
+ [Generate symmetric keys](cloudhsm-cli-generate-symmetric-keys.md)
+ [Generate asymmetric keys](cloudhsm-cli-generate-asymmetric-keys.md)
+ [Related topics](cloudhsm-cli-generate-keys-seealso.md)

# Generate symmetric keys with CloudHSM CLI
<a name="cloudhsm-cli-generate-symmetric-keys"></a>

Use the commands listed in **[The generate-symmetric category in CloudHSM CLI](cloudhsm_cli-key-generate-symmetric.md)** to generate symmetric keys for AWS CloudHSM. To see all available options, use the **help key generate-symmetric** command.

## Generate an AES key
<a name="cloudhsm-cli-generate-symmetric-aes"></a>

Use the **key generate-symmetric aes** command to generate AES keys. To see all available options, use the **help key generate-symmetric aes** command.

**Example**  
The following example generates a 32-byte AES key.  

```
aws-cloudhsm > key generate-symmetric aes \
    --label aes-example \
    --key-length-bytes 32
```

### Arguments
<a name="cloudhsm-cli-generate-symmetric-aes-args"></a>

***<LABEL>***  
Specifies a user-defined label for the AES key.  
Required: Yes

***<KEY-LENGTH-BYTES>***  
Specifies the key length in bytes.  

Valid values:
+ 16, 24, and 32
Required: Yes

***<KEY\$1ATTRIBUTES>***  
Specifies a space separated list of key attributes to set for the generated AES key in the form of `KEY_ATTRIBUTE_NAME=KEY_ATTRIBUTE_VALUE` (for example, `sign=true`)  
For a list of supported AWS CloudHSM key attributes, see [Key attributes for CloudHSM CLI](cloudhsm_cli-key-attributes.md).  
Required: No

***<SESSION>***  
Creates a key that exists only in the current session. The key cannot be recovered after the session ends. Use this parameter when you need a key only briefly, such as a wrapping key that encrypts, and then quickly decrypts, another key. Do not use a session key to encrypt data that you might need to decrypt after the session ends.  
To change a session key to a persistent (token) key, use [key set-attribute](cloudhsm_cli-key-set-attribute.md).  
By default, when keys are generated they are persistent/token keys. Using <SESSION> changes this, ensuring a key generated with this argument is a session/ephemeral  
Required: No

### Generate generic secret key
<a name="cloudhsm-cli-generate-symmetric-secret"></a>

Use the **key generate-symmetric generic-secret** command to generate generic secret keys. To see all available options, use the **help key generate-symmetric generic-secret** command.

**Example**  
The following example generates a 32-byte generic secret key.  

```
aws-cloudhsm > key generate-symmetric generic-secret \
    --label generic-secret-example \
    --key-length-bytes 32
```

#### Arguments
<a name="cloudhsm-cli-generate-symmetric-secret-args"></a>

***<LABEL>***  
Specifies a user-defined label for the generic secret key.  
Required: Yes

***<KEY-LENGTH-BYTES>***  
Specifies the key length in bytes.  

Valid values:
+ 1 to 800
Required: Yes

***<KEY\$1ATTRIBUTES>***  
Specifies a space separated list of key attributes to set for the generated generic secret key in the form of `KEY_ATTRIBUTE_NAME=KEY_ATTRIBUTE_VALUE` (for example, `sign=true`)  
For a list of supported AWS CloudHSM key attributes, see [Key attributes for CloudHSM CLI](cloudhsm_cli-key-attributes.md).  
Required: No

***<SESSION>***  
Creates a key that exists only in the current session. The key cannot be recovered after the session ends. Use this parameter when you need a key only briefly, such as a wrapping key that encrypts, and then quickly decrypts, another key. Do not use a session key to encrypt data that you might need to decrypt after the session ends.  
To change a session key to a persistent (token) key, use [key set-attribute](cloudhsm_cli-key-set-attribute.md).  
By default, when keys are generated they are persistent/token keys. Using <SESSION> changes this, ensuring a key generated with this argument is a session/ephemeral  
Required: No

# Generate asymmetric keys using CloudHSM CLI
<a name="cloudhsm-cli-generate-asymmetric-keys"></a>

Use the commands listed in **[The generate-asymmetric-pair category in CloudHSM CLI](cloudhsm_cli-key-generate-asymmetric-pair.md)** to generate asymmetric key pairs for AWS CloudHSM clusters.

## Generate an RSA key
<a name="cloudhsm-cli-generate-asymmetric-rsa"></a>

Use the **key generate-asymmetric-pair rsa** command to generate an RSA key pair. To see all available options, use the **help key generate-asymmetric-pair rsa** command.

**Example**  
The following example generates an RSA 2048-bit key pair.  

```
aws-cloudhsm > key generate-asymmetric-pair rsa \
    --public-exponent 65537 \
    --modulus-size-bits 2048 \
    --public-label rsa-public-example \
    --private-label rsa-private-example
```

### Arguments
<a name="cloudhsm-cli-generate-asymmetric-rsa-args"></a>

***<PUBLIC\$1LABEL>***  
Specifies a user-defined label for the public-key.  
Required: Yes

***<PRIVATE\$1LABEL>***  
Specifies a user-defined label for the private-key.  
Required: Yes

***<MODULUS\$1SIZE\$1BITS>***  
Specifies the length of the modulus in bits. The minimum value is 2048.   
Required: Yes

***<PUBLIC\$1EXPONENT>***  
Specifies the public exponent. The value must be an odd number greater than or equal to 65537.  
Required: Yes

***<PUBLIC\$1KEY\$1ATTRIBUTES>***  
Specifies a space-separated list of key attributes to set for the generated RSA public key in the form of `KEY_ATTRIBUTE_NAME=KEY_ATTRIBUTE_VALUE` (for example, `sign=true`).  
For a list of supported AWS CloudHSM key attributes, see [Key attributes for CloudHSM CLI](cloudhsm_cli-key-attributes.md).  
Required: No

***<SESSION>***  
Creates a key that exists only in the current session. The key cannot be recovered after the session ends. Use this parameter when you need a key only briefly, such as a wrapping key that encrypts, and then quickly decrypts, another key. Do not use a session key to encrypt data that you might need to decrypt after the session ends.  
To change a session key to a persistent (token) key, use [key set-attribute](cloudhsm_cli-key-set-attribute.md).  
By default, when keys are generated they are persistent/token keys. Using <SESSION> changes this, ensuring a key generated with this argument is a session/ephemeral  
Required: No

### Generate EC (elliptic curve cryptography) key pairs
<a name="cloudhsm-cli-generate-asymmetric-ec"></a>

Use the **key generate-asymmetric-pair ec** command to generate an EC key pair. To see all available options,including a list of the supported elliptic curves, use the **help key generate-asymmetric-pair ec** command.

**Example**  
The following example generates an EC key pair using the Secp384r1 elliptic curve.  

```
aws-cloudhsm > key generate-asymmetric-pair ec \
    --curve secp384r1 \
    --public-label ec-public-example \
    --private-label ec-private-example
```

#### Arguments
<a name="cloudhsm-cli-generate-asymmetric-ec-args"></a>

***<PUBLIC\$1LABEL>***  
Specifies a user-defined label for the public-key. The maximum size allowable for `label` is 127 characters for Client SDK 5.11 and after. Client SDK 5.10 and before has a limit of 126 characters.  
Required: Yes

***<PRIVATE\$1LABEL>***  
Specifies a user-defined label for the private-key. The maximum size allowable for `label` is 127 characters for Client SDK 5.11 and after. Client SDK 5.10 and before has a limit of 126 characters.  
Required: Yes

***<CURVE>***  
Specifies the identifier for the elliptic curve.  

Valid values:
+ prime256v1
+ secp256r1
+ secp224r1
+ secp384r1
+ secp256k1
+ secp521r1
+ ed25519 (only supported on hsm2m.medium instances in non-FIPS mode)
Required: Yes

***<PUBLIC\$1KEY\$1ATTRIBUTES>***  
Specifies a space-separated list of key attributes to set for the generated EC public key in the form of `KEY_ATTRIBUTE_NAME=KEY_ATTRIBUTE_VALUE` (for example, `verify=true`).  
For a list of supported AWS CloudHSM key attributes, see [Key attributes for CloudHSM CLI](cloudhsm_cli-key-attributes.md).  
Required: No

***<PRIVATE\$1KEY\$1ATTRIBUTES>***  
Specifies a space-separated list of key attributes to set for the generated EC private key in the form of `KEY_ATTRIBUTE_NAME=KEY_ATTRIBUTE_VALUE` (for example, `sign=true`).  
For a list of supported AWS CloudHSM key attributes, see [Key attributes for CloudHSM CLI](cloudhsm_cli-key-attributes.md).  
Required: No

***<SESSION>***  
Creates a key that exists only in the current session. The key cannot be recovered after the session ends. Use this parameter when you need a key only briefly, such as a wrapping key that encrypts, and then quickly decrypts, another key. Do not use a session key to encrypt data that you might need to decrypt after the session ends.  
To change a session key to a persistent (token) key, use [key set-attribute](cloudhsm_cli-key-set-attribute.md).  
By default, keys that are generated are persistent (token) keys. Passing in <SESSION> changes this, ensuring a key generated with this argument is a session (ephemeral) key.  
Required: No

# AWS CloudHSM key related topics
<a name="cloudhsm-cli-generate-keys-seealso"></a>

See the following sections for additional information about keys in AWS CloudHSM.
+ [Key attributes for CloudHSM CLI](cloudhsm_cli-key-attributes.md)
+ [The generate-asymmetric-pair category in CloudHSM CLI](cloudhsm_cli-key-generate-asymmetric-pair.md)
+ [The generate-symmetric category in CloudHSM CLI](cloudhsm_cli-key-generate-symmetric.md)

# Delete keys using CloudHSM CLI
<a name="manage-keys-cloudhsm-cli-delete"></a>

Use the example in this topic to delete a key with [CloudHSM CLI](cloudhsm_cli.md). Only key owners can delete keys.

**Topics**
+ [Example: Delete a key](#cloudhsm-cli-delete-keys-example)
+ [Related topics](#cloudhsm-cli-delete-keys-seealso)

## Example: Delete a key
<a name="cloudhsm-cli-delete-keys-example"></a>

1. Run the **key list** command to identify the key you want to delete:

   ```
   aws-cloudhsm > key list --filter attr.label="my_key_to_delete" --verbose
   {
     "error_code": 0,
     "data": {
       "matched_keys": [
         {
           "key-reference": "0x0000000000540011",
           "key-info": {
             "key-owners": [
               {
                 "username": "my_crypto_user",
                 "key-coverage": "full"
               }
             ],
             "shared-users": [],
           "key-quorum-values": {
             "manage-key-quorum-value": 0,
             "use-key-quorum-value": 0
           },
             "cluster-coverage": "full"
           },
           "attributes": {
             "key-type": "rsa",
             "label": "my_key_to_delete",
             "id": "",
             "check-value": "0x29bbd1",
             "class": "private-key",
             "encrypt": false,
             "decrypt": true,
             "token": true,
             "always-sensitive": true,
             "derive": false,
             "destroyable": true,
             "extractable": true,
             "local": true,
             "modifiable": true,
             "never-extractable": false,
             "private": true,
             "sensitive": true,
             "sign": true,
             "trusted": false,
             "unwrap": true,
             "verify": false,
             "wrap": false,
             "wrap-with-trusted": false,
             "key-length-bytes": 1217,
             "public-exponent": "0x010001",
             "modulus": "0x8b3a7c20618e8be08220ed8ab2c8550b65fc1aad8d4cf04fbf2be685f97eeb78fcbbad9b02cd91a3b15e990c2a7c7cdeff0b730576c6c5630a8509a778a96acbc7c36931e9a86e8956fbd07f0863404ce06c8bd68256784be9f5b258a35e229ce7f630228b9323b4e1f14a0384ead90bdf07dc762f710fc5663887d0787ad98d64bbe303134f545acb2ab194fee6edaecd4dd5cf31ff7f7491e37d7a850ab23247414b42d9abdd5de89b78fd464560df29a90607e9d462f21b22365da419021fb9f28ea7e6fdb1f40bf83aaf1636fba5e475ad19889cfe3f28186a969b4826c39466c0855c974d1fb723d111e4a32ab6e32b3129bc95c9206fced160015d8b2f",
             "modulus-size-bits": 2048
           }
         }
       ],
       "total_key_count": 1,
       "returned_key_count": 1
     }
   ```

1. After identifying the key, run the **key delete** with the key's unique `label` attribute to delete the key:

   ```
   aws-cloudhsm > key delete --filter attr.label="my_key_to_delete"
   {
     "error_code": 0,
     "data": {
       "message": "Key deleted successfully"
     }
   }
   ```

1. Run the **key list** command with the key's unique `label` attribute and confirm the key has been deleted. As shown in the following example, no key with the label `my_key_to_delete` is in the HSM cluster:

   ```
   aws-cloudhsm > key list --filter attr.label="my_key_to_delete"
   {
     "error_code": 0,
     "data": {
       "matched_keys": [],
       "total_key_count": 0,
       "returned_key_count": 0
     }
   }
   ```

## Related topics
<a name="cloudhsm-cli-delete-keys-seealso"></a>
+ [Key attributes for CloudHSM CLI](cloudhsm_cli-key-attributes.md)
+ [Delete a key with CloudHSM CLI](cloudhsm_cli-key-delete.md)

# Share and unshare keys using CloudHSM CLI
<a name="manage-keys-cloudhsm-cli-share"></a>

Use the commands in this topic to share and unshare keys in [CloudHSM CLI](cloudhsm_cli.md). In AWS CloudHSM, the crypto user (CU) who creates the key owns it. The owner can use the **key share** and **key unshare** commands to share and unshare the key with other CUs. Users with whom the key is shared can use the key in cryptographic operations, but they cannot delete, export, share, unshare, derive, or wrap the key.

Before you can share a key, you must log in to the HSM as the crypto user (CU) who owns the key.

**Topics**
+ [Example: Sharing and unsharing a key](#w2aac15c21c11b9)
+ [Related topics](#cloudhsm-cli-share-keys-seealso)

## Example: Sharing and unsharing a key
<a name="w2aac15c21c11b9"></a>

**Example**  
The following example shows how to share and unshare a key with crypto user (CU) `alice`. Along with the **key share** and **key unshare** commands, sharing and unsharing commands also requires a specific key using [CloudHSM CLI key filters](manage-keys-cloudhsm-cli-filtering.md) and the specific username of the user whom the key will be shared or unshared with.  

1. Start by running the **key list** command with a filter to return a specific key and see whom the key is already shared with.

   ```
   aws-cloudhsm > key list --filter attr.label="rsa_key_to_share" --verbose
   {
     "error_code": 0,
     "data": {
       "matched_keys": [
         {
           "key-reference": "0x00000000001c0686",
           "key-info": {
             "key-owners": [
               {
                 "username": "cu3",
                 "key-coverage": "full"
               }
             ],
             "shared-users": [
               {
                 "username": "cu2",
                 "key-coverage": "full"
               },
               {
                 "username": "cu1",
                 "key-coverage": "full"
               },
               {
                 "username": "cu4",
                 "key-coverage": "full"
               },
               {
                 "username": "cu5",
                 "key-coverage": "full"
               },
               {
                 "username": "cu6",
                 "key-coverage": "full"
               },
               {
                 "username": "cu7",
                 "key-coverage": "full"
               },
             ],
             "key-quorum-values": {
               "manage-key-quorum-value": 0,
               "use-key-quorum-value": 0
             },
             "cluster-coverage": "full"
           },
           "attributes": {
             "key-type": "rsa",
             "label": "rsa_key_to_share",
             "id": "",
             "check-value": "0xae8ff0",
             "class": "private-key",
             "encrypt": false,
             "decrypt": true,
             "token": true,
             "always-sensitive": true,
             "derive": false,
             "destroyable": true,
             "extractable": true,
             "local": true,
             "modifiable": true,
             "never-extractable": false,
             "private": true,
             "sensitive": true,
             "sign": true,
             "trusted": false,
             "unwrap": true,
             "verify": false,
             "wrap": false,
             "wrap-with-trusted": false,
             "key-length-bytes": 1219,
             "public-exponent": "0x010001",
             "modulus": "0xa8855cba933cec0c21a4df0450ec31675c024f3e65b2b215a53d2bda6dcd191f75729150b59b4d86df58254c8f518f7d000cc04d8e958e7502c7c33098e28da4d94378ef34fb57d1cc7e042d9119bd79be0df728421a980a397095157da24cf3cc2b6dab12225d33fdca11f0c6ed1a5127f12488cda9a556814b39b06cd8373ff5d371db2212887853621b8510faa7b0779fbdec447e1f1d19f343acb02b22526487a31f6c704f8f003cb4f7013136f90cc17c2c20e414dc1fc7bcfb392d59c767900319679fc3307388633485657ce2e1a3deab0f985b0747ef4ed339de78147d1985d14fdd8634219321e49e3f5715e79c298f18658504bab04086bfbdcd3b",
             "modulus-size-bits": 2048
           }
         }
       ],
       "total_key_count": 1,
       "returned_key_count": 1
     }
   }
   ```

1. View the `shared-users` output to identify whom the key is currently shared with.

1. To share this key with crypto user (CU) `alice`, enter the following command:

   ```
   aws-cloudhsm > key share --filter attr.label="rsa_key_to_share" attr.class=private-key --username alice --role crypto-user
   {
     "error_code": 0,
     "data": {
       "message": "Key shared successfully"
     }
   }
   ```

   Note that, along with the **key share** command, this command uses the unique label of the key and the name of the user whom the key will be shared with.

1. Run the **key list** command to confirm that the key has been shared with `alice`:

   ```
   aws-cloudhsm > key list --filter attr.label="rsa_key_to_share" --verbose
   {
     "error_code": 0,
     "data": {
       "matched_keys": [
         {
           "key-reference": "0x00000000001c0686",
           "key-info": {
             "key-owners": [
               {
                 "username": "cu3",
                 "key-coverage": "full"
               }
             ],
             "shared-users": [
               {
                 "username": "cu2",
                 "key-coverage": "full"
               },
               {
                 "username": "cu1",
                 "key-coverage": "full"
               },
               {
                 "username": "cu4",
                 "key-coverage": "full"
               },
               {
                 "username": "cu5",
                 "key-coverage": "full"
               },
               {
                 "username": "cu6",
                 "key-coverage": "full"
               },
               {
                 "username": "cu7",
                 "key-coverage": "full"
               },
               {
                 "username": "alice",
                 "key-coverage": "full"
               }
             ],
             "key-quorum-values": {
               "manage-key-quorum-value": 0,
               "use-key-quorum-value": 0
             },
             "cluster-coverage": "full"
           },
           "attributes": {
             "key-type": "rsa",
             "label": "rsa_key_to_share",
             "id": "",
             "check-value": "0xae8ff0",
             "class": "private-key",
             "encrypt": false,
             "decrypt": true,
             "token": true,
             "always-sensitive": true,
             "derive": false,
             "destroyable": true,
             "extractable": true,
             "local": true,
             "modifiable": true,
             "never-extractable": false,
             "private": true,
             "sensitive": true,
             "sign": true,
             "trusted": false,
             "unwrap": true,
             "verify": false,
             "wrap": false,
             "wrap-with-trusted": false,
             "key-length-bytes": 1219,
             "public-exponent": "0x010001",
             "modulus": "0xa8855cba933cec0c21a4df0450ec31675c024f3e65b2b215a53d2bda6dcd191f75729150b59b4d86df58254c8f518f7d000cc04d8e958e7502c7c33098e28da4d94378ef34fb57d1cc7e042d9119bd79be0df728421a980a397095157da24cf3cc2b6dab12225d33fdca11f0c6ed1a5127f12488cda9a556814b39b06cd8373ff5d371db2212887853621b8510faa7b0779fbdec447e1f1d19f343acb02b22526487a31f6c704f8f003cb4f7013136f90cc17c2c20e414dc1fc7bcfb392d59c767900319679fc3307388633485657ce2e1a3deab0f985b0747ef4ed339de78147d1985d14fdd8634219321e49e3f5715e79c298f18658504bab04086bfbdcd3b",
             "modulus-size-bits": 2048
           }
         }
       ],
       "total_key_count": 1,
       "returned_key_count": 1
     }
   }
   ```

1. To unshare the same key with `alice`, run the following **unshare** command:

   ```
   aws-cloudhsm > key unshare --filter attr.label="rsa_key_to_share" attr.class=private-key --username alice --role crypto-user
   {
     "error_code": 0,
     "data": {
       "message": "Key unshared successfully"
     }
   }
   ```

   Note that, along with the **key unshare** command, this command uses the unique label of the key and the name of the user whom the key will be shared with.

1. Run the **key list** command again and confirm the key was unshared with crypto user `alice`:

   ```
   aws-cloudhsm > key list --filter attr.label="rsa_key_to_share" --verbose
   {
     "error_code": 0,
     "data": {
       "matched_keys": [
         {
           "key-reference": "0x00000000001c0686",
           "key-info": {
             "key-owners": [
               {
                 "username": "cu3",
                 "key-coverage": "full"
               }
             ],
             "shared-users": [
               {
                 "username": "cu2",
                 "key-coverage": "full"
               },
               {
                 "username": "cu1",
                 "key-coverage": "full"
               },
               {
                 "username": "cu4",
                 "key-coverage": "full"
               },
               {
                 "username": "cu5",
                 "key-coverage": "full"
               },
               {
                 "username": "cu6",
                 "key-coverage": "full"
               },
               {
                 "username": "cu7",
                 "key-coverage": "full"
               },
             ],
             "key-quorum-values": {
               "manage-key-quorum-value": 0,
               "use-key-quorum-value": 0
             },
             "cluster-coverage": "full"
           },
           "attributes": {
             "key-type": "rsa",
             "label": "rsa_key_to_share",
             "id": "",
             "check-value": "0xae8ff0",
             "class": "private-key",
             "encrypt": false,
             "decrypt": true,
             "token": true,
             "always-sensitive": true,
             "derive": false,
             "destroyable": true,
             "extractable": true,
             "local": true,
             "modifiable": true,
             "never-extractable": false,
             "private": true,
             "sensitive": true,
             "sign": true,
             "trusted": false,
             "unwrap": true,
             "verify": false,
             "wrap": false,
             "wrap-with-trusted": false,
             "key-length-bytes": 1219,
             "public-exponent": "0x010001",
             "modulus": "0xa8855cba933cec0c21a4df0450ec31675c024f3e65b2b215a53d2bda6dcd191f75729150b59b4d86df58254c8f518f7d000cc04d8e958e7502c7c33098e28da4d94378ef34fb57d1cc7e042d9119bd79be0df728421a980a397095157da24cf3cc2b6dab12225d33fdca11f0c6ed1a5127f12488cda9a556814b39b06cd8373ff5d371db2212887853621b8510faa7b0779fbdec447e1f1d19f343acb02b22526487a31f6c704f8f003cb4f7013136f90cc17c2c20e414dc1fc7bcfb392d59c767900319679fc3307388633485657ce2e1a3deab0f985b0747ef4ed339de78147d1985d14fdd8634219321e49e3f5715e79c298f18658504bab04086bfbdcd3b",
             "modulus-size-bits": 2048
           }
         }
       ],
       "total_key_count": 1,
       "returned_key_count": 1
     }
   }
   ```

## Related topics
<a name="cloudhsm-cli-share-keys-seealso"></a>
+ [Key attributes for CloudHSM CLI](cloudhsm_cli-key-attributes.md)
+ [Share a key using CloudHSM CLI](cloudhsm_cli-key-share.md)
+ [Unshare a key using CloudHSM CLI](cloudhsm_cli-key-unshare.md)
+ [Filter keys using CloudHSM CLI](manage-keys-cloudhsm-cli-filtering.md)

# Filter keys using CloudHSM CLI
<a name="manage-keys-cloudhsm-cli-filtering"></a>

Use the following key commands to utilize the standardized key filtration mechanisms for [CloudHSM CLI](cloudhsm_cli.md).
+ **key list**
+ **key delete**
+ **key share**
+ **key unshare**
+ **key set-attribute**

To select and/or filter keys with CloudHSM CLI, key commands utilize a standardized filtration mechanism based on [Key attributes for CloudHSM CLI](cloudhsm_cli-key-attributes.md). A key or set of keys can be specified in key commands by using one or more AWS CloudHSM attributes that can identify a single key or multiple keys. The key filtration mechanism operates only on keys that the currently logged in user owns and shares, as well as all public keys in the AWS CloudHSM cluster.

**Topics**
+ [Requirements](#chsm-cli-filtering-requirements)
+ [Filtering to find a single key](#chsm-cli-filtering-examples)
+ [Filtration Errors](#manage-keys-chsm-cli-filter-error)
+ [Related topics](#manage-keys-chsm-cli-filtering-seealso)

## Requirements
<a name="chsm-cli-filtering-requirements"></a>

To filter keys, you must be a logged in as a crypto user (CUs).

## Filtering to find a single key
<a name="chsm-cli-filtering-examples"></a>

Please note that in the following examples, each attribute that is used as a filter must be written in the form of `attr.KEY_ATTRIBUTE_NAME=KEY_ATTRIBUTE_VALUE`. For example, if you want to filter by the label attribute, you will write `attr.label=my_label`.

**Example Use a single attribute to find a single key**  
This example demonstrates how to filter to a single unique key using only a single identifying attribute.  

```
aws-cloudhsm > key list --filter attr.label="my_unique_key_label" --verbose
{
  "error_code": 0,
  "data": {
    "matched_keys": [
      {
        "key-reference": "0x00000000001c0686",
        "key-info": {
          "key-owners": [
            {
              "username": "cu1",
              "key-coverage": "full"
            }
          ],
          "shared-users": [
            {
              "username": "alice",
              "key-coverage": "full"
            }
          ],
          "key-quorum-values": {
            "manage-key-quorum-value": 0,
            "use-key-quorum-value": 0
          },
          "cluster-coverage": "full"
        },
        "attributes": {
          "key-type": "rsa",
          "label": "my_unique_key_label",
          "id": "",
          "check-value": "0xae8ff0",
          "class": "private-key",
          "encrypt": false,
          "decrypt": true,
          "token": true,
          "always-sensitive": true,
          "derive": false,
          "destroyable": true,
          "extractable": true,
          "local": true,
          "modifiable": true,
          "never-extractable": false,
          "private": true,
          "sensitive": true,
          "sign": true,
          "trusted": false,
          "unwrap": true,
          "verify": false,
          "wrap": false,
          "wrap-with-trusted": false,
          "key-length-bytes": 1219,
          "public-exponent": "0x010001",
          "modulus": "0xa8855cba933cec0c21a4df0450ec31675c024f3e65b2b215a53d2bda6dcd191f75729150b59b4d86df58254c8f518f7d000cc04d8e958e7502c7c33098e28da4d94378ef34fb57d1cc7e042d9119bd79be0df728421a980a397095157da24cf3cc2b6dab12225d33fdca11f0c6ed1a5127f12488cda9a556814b39b06cd8373ff5d371db2212887853621b8510faa7b0779fbdec447e1f1d19f343acb02b22526487a31f6c704f8f003cb4f7013136f90cc17c2c20e414dc1fc7bcfb392d59c767900319679fc3307388633485657ce2e1a3deab0f985b0747ef4ed339de78147d1985d14fdd8634219321e49e3f5715e79c298f18658504bab04086bfbdcd3b",
          "modulus-size-bits": 2048
        }
      }
    ],
    "total_key_count": 1,
    "returned_key_count": 1
  }
}
```

**Example Use a multiple attributes to find a single key**  
The following example demonstrates how to find a single key using multiple key attributes.  

```
aws-cloudhsm > key list --filter attr.key-type=rsa attr.class=private-key attr.check-value=0x29bbd1 --verbose
{
  "error_code": 0,
  "data": {
    "matched_keys": [
      {
        "key-reference": "0x0000000000540011",
        "key-info": {
          "key-owners": [
            {
              "username": "cu3",
              "key-coverage": "full"
            }
          ],
          "shared-users": [
            {
              "username": "cu2",
              "key-coverage": "full"
            }
          ],
          "key-quorum-values": {
            "manage-key-quorum-value": 0,
            "use-key-quorum-value": 0
          },
          "cluster-coverage": "full"
        },
        "attributes": {
          "key-type": "rsa",
          "label": "my_crypto_user",
          "id": "",
          "check-value": "0x29bbd1",
          "class": "my_test_key",
          "encrypt": false,
          "decrypt": true,
          "token": true,
          "always-sensitive": true,
          "derive": false,
          "destroyable": true,
          "extractable": true,
          "local": true,
          "modifiable": true,
          "never-extractable": false,
          "private": true,
          "sensitive": true,
          "sign": true,
          "trusted": false,
          "unwrap": true,
          "verify": false,
          "wrap": false,
          "wrap-with-trusted": false,
          "key-length-bytes": 1217,
          "public-exponent": "0x010001",
          "modulus": "0x8b3a7c20618e8be08220ed8ab2c8550b65fc1aad8d4cf04fbf2be685f97eeb78fcbbad9b02cd91a3b15e990c2a7c7cdeff0b730576c6c5630a8509a778a96acbc7c36931e9a86e8956fbd07f0863404ce06c8bd68256784be9f5b258a35e229ce7f630228b9323b4e1f14a0384ead90bdf07dc762f710fc5663887d0787ad98d64bbe303134f545acb2ab194fee6edaecd4dd5cf31ff7f7491e37d7a850ab23247414b42d9abdd5de89b78fd464560df29a90607e9d462f21b22365da419021fb9f28ea7e6fdb1f40bf83aaf1636fba5e475ad19889cfe3f28186a969b4826c39466c0855c974d1fb723d111e4a32ab6e32b3129bc95c9206fced160015d8b2f",
          "modulus-size-bits": 2048
        }
      }
    ],
    "total_key_count": 1,
    "returned_key_count": 1
  }
}
```

**Example Filtering to find a set of keys**  
The following example demonstrates how to filter to find a set of private rsa keys.  

```
aws-cloudhsm > key list --filter attr.key-type=rsa attr.class=private-key --verbose
{
  "error_code": 0,
  "data": {
    "matched_keys": [
      {
        "key-reference": "0x00000000001c0686",
        "key-info": {
          "key-owners": [
            {
              "username": "my_crypto_user",
              "key-coverage": "full"
            }
          ],
          "shared-users": [
            {
              "username": "cu2",
              "key-coverage": "full"
            },
            {
              "username": "cu1",
              "key-coverage": "full"
            },
          ],
          "key-quorum-values": {
            "manage-key-quorum-value": 0,
            "use-key-quorum-value": 0
          },
          "cluster-coverage": "full"
        },
        "attributes": {
          "key-type": "rsa",
          "label": "rsa_key_to_share",
          "id": "",
          "check-value": "0xae8ff0",
          "class": "private-key",
          "encrypt": false,
          "decrypt": true,
          "token": true,
          "always-sensitive": true,
          "derive": false,
          "destroyable": true,
          "extractable": true,
          "local": true,
          "modifiable": true,
          "never-extractable": false,
          "private": true,
          "sensitive": true,
          "sign": true,
          "trusted": false,
          "unwrap": true,
          "verify": false,
          "wrap": false,
          "wrap-with-trusted": false,
          "key-length-bytes": 1219,
          "public-exponent": "0x010001",
          "modulus": "0xa8855cba933cec0c21a4df0450ec31675c024f3e65b2b215a53d2bda6dcd191f75729150b59b4d86df58254c8f518f7d000cc04d8e958e7502c7c33098e28da4d94378ef34fb57d1cc7e042d9119bd79be0df728421a980a397095157da24cf3cc2b6dab12225d33fdca11f0c6ed1a5127f12488cda9a556814b39b06cd8373ff5d371db2212887853621b8510faa7b0779fbdec447e1f1d19f343acb02b22526487a31f6c704f8f003cb4f7013136f90cc17c2c20e414dc1fc7bcfb392d59c767900319679fc3307388633485657ce2e1a3deab0f985b0747ef4ed339de78147d1985d14fdd8634219321e49e3f5715e79c298f18658504bab04086bfbdcd3b",
          "modulus-size-bits": 2048
        }
      },
      {
        "key-reference": "0x0000000000540011",
        "key-info": {
          "key-owners": [
            {
              "username": "my_crypto_user",
              "key-coverage": "full"
            }
          ],
          "shared-users": [
            {
              "username": "cu2",
              "key-coverage": "full"
            }
          ],
          "key-quorum-values": {
            "manage-key-quorum-value": 0,
            "use-key-quorum-value": 0
          },
          "cluster-coverage": "full"
        },
        "attributes": {
          "key-type": "rsa",
          "label": "my_test_key",
          "id": "",
          "check-value": "0x29bbd1",
          "class": "private-key",
          "encrypt": false,
          "decrypt": true,
          "token": true,
          "always-sensitive": true,
          "derive": false,
          "destroyable": true,
          "extractable": true,
          "local": true,
          "modifiable": true,
          "never-extractable": false,
          "private": true,
          "sensitive": true,
          "sign": true,
          "trusted": false,
          "unwrap": true,
          "verify": false,
          "wrap": false,
          "wrap-with-trusted": false,
          "key-length-bytes": 1217,
          "public-exponent": "0x010001",
          "modulus": "0x8b3a7c20618e8be08220ed8ab2c8550b65fc1aad8d4cf04fbf2be685f97eeb78fcbbad9b02cd91a3b15e990c2a7c7cdeff0b730576c6c5630a8509a778a96acbc7c36931e9a86e8956fbd07f0863404ce06c8bd68256784be9f5b258a35e229ce7f630228b9323b4e1f14a0384ead90bdf07dc762f710fc5663887d0787ad98d64bbe303134f545acb2ab194fee6edaecd4dd5cf31ff7f7491e37d7a850ab23247414b42d9abdd5de89b78fd464560df29a90607e9d462f21b22365da419021fb9f28ea7e6fdb1f40bf83aaf1636fba5e475ad19889cfe3f28186a969b4826c39466c0855c974d1fb723d111e4a32ab6e32b3129bc95c9206fced160015d8b2f",
          "modulus-size-bits": 2048
        }
      }
    ],
    "total_key_count": 2,
    "returned_key_count": 2
  }
}
```

## Filtration Errors
<a name="manage-keys-chsm-cli-filter-error"></a>

Certain key operations can only be performed on a single key at a time. For these operations, the CloudHSM CLI will provide an error if the filtration criteria is not sufficiently refined and multiple keys match the criteria. One such example is shown below with the key delete.

**Example Filtration Error when matching too many keys**  

```
aws-cloudhsm > key delete --filter attr.key-type=rsa
{
  "error_code": 1,
  "data": "Key selection criteria matched 48 keys. Refine selection criteria to select a single key."
}
```

## Related topics
<a name="manage-keys-chsm-cli-filtering-seealso"></a>
+ [Key attributes for CloudHSM CLI](cloudhsm_cli-key-attributes.md)

# Mark a key as trusted using CloudHSM CLI
<a name="manage-keys-cloudhsm-cli-trusted"></a>

The content in this section provides instructions on using CloudHSM CLI to mark a key as trusted.

1. Using the [CloudHSM CLI **login** command](cloudhsm_cli-login.md), log in as a crypto user (CU).

1. Use the **key list** command to identify the key reference of the key you want to mark as trusted. The following example lists the key with the label `test_aes_trusted`.

   ```
   aws-cloudhsm > key list --filter attr.label=test_aes_trusted
           {
     "error_code": 0,
     "data": {
       "matched_keys": [
         {
           "key-reference": "0x0000000000200333",
           "attributes": {
             "label": "test_aes_trusted"
           }
         }
       ],
       "total_key_count": 1,
       "returned_key_count": 1
     }
   }
   ```

1. Using the [Log out of an HSM using CloudHSM CLI](cloudhsm_cli-logout.md) command, log out as a crypto user (CU).

1. Using the [Log in to an HSM using CloudHSM CLI](cloudhsm_cli-login.md) command, log in as an admin.

1. Using the [key set-attribute](cloudhsm_cli-key-set-attribute.md) command with the key reference you identified in step 2, set the key's trusted value to true:

   ```
   aws-cloudhsm > key set-attribute --filter key-reference=<Key Reference> --name trusted --value true
   {
     "error_code": 0,
     "data": {
       "message": "Attribute set successfully"
     }
   }
   ```

# Manage quorum authentication (M of N access control) using CloudHSM CLI
<a name="key-quorum-auth-chsm-cli"></a>

The hardware security modules (HSMs) in your AWS CloudHSM cluster support quorum authentication, also known as M of N access control. With quorum authentication, no single user on the HSM can perform quorum-controlled operations. Instead, a minimum number of HSM users (at least 2) must cooperate to do these operations. Quorum authentication adds an extra layer of protection by requiring approvals from multiple HSM users.

Quorum authentication can control the following operations:
+ HSM key usage and management by a [crypto-user](understanding-users.md#crypto-user-chsm-cli) – Creating signatures with a key, or wrapping, unwrapping, sharing, unsharing, and setting an attribute of a key.

**Important considerations**
+ An HSM user can sign their own quorum token—that is, the requesting user can provide one of the required approvals for quorum authentication.
+ You choose the minimum number of quorum approvers for quorum-controlled operations. The smallest number you can choose is two (2), and the largest number you can choose is eight (8).
+ The HSM can store up to 1,024 quorum tokens. If the HSM already has 1,024 tokens when you try to create a new one, the HSM purges one of the expired tokens. By default, tokens expire ten minutes after their creation.
+ If multi-factor authentication (MFA) is enabled, the cluster uses the same key for quorum authentication and for MFA. For more information about using quorum authentication and MFA, see [Using CloudHSM CLI to manage MFA](login-mfa-token-sign.md).
+ Each HSM can only contain one token per Admin service at a time, but multiple tokens per Crypto User service.

The following topics provide more information about quorum authentication in AWS CloudHSM.

**Topics**
+ [Quorum authentication process for CloudHSM CLI](key-quorum-auth-chsm-cli-overview.md)
+ [Supported AWS CloudHSM service names and types for quorum authentication with CloudHSM CLI](key-quorum-auth-chsm-cli-service-names.md)
+ [Set up quorum authentication for AWS CloudHSM crypto-users using CloudHSM CLI](key-quorum-auth-chsm-cli-first-time.md)
+ [Key management and usage with quorum authentication enabled for AWS CloudHSM using CloudHSM CLI](key-quorum-auth-chsm-cli-crypto-user.md)

# Quorum authentication process for CloudHSM CLI
<a name="key-quorum-auth-chsm-cli-overview"></a>

The following steps summarize the quorum authentication processes for CloudHSM CLI. For the specific steps and tools, see [Key management and usage with quorum authentication enabled for AWS CloudHSM using CloudHSM CLI](key-quorum-auth-chsm-cli-crypto-user.md).

1. Each hardware security module (HSM) user creates an asymmetric key for signing. Users do this outside of the HSM, taking care to protect the key appropriately.

1. Each HSM user logs in to the HSM and registers the public part of their signing key (the public key) with the HSM.

1. When an HSM user wants to do a quorum-controlled operation, the same user logs in to the HSM and gets a *quorum token*.

1. The HSM user gives the quorum token to one or more other HSM users and asks for their approval.

1. The other HSM users approve by using their keys to cryptographically sign the quorum token. This occurs outside the HSM.

1. When the HSM user has the required number of approvals, the same user logs in to the HSM and runs the quorum-controlled operation with the **--approval** argument, supplying the signed quorum token file, which contains all necessary approvals (signatures).

1. The HSM uses the registered public keys of each signer to verify the signatures. If the signatures are valid, the HSM approves the token and the quorum-controlled operation is performed.

# Supported AWS CloudHSM service names and types for quorum authentication with CloudHSM CLI
<a name="key-quorum-auth-chsm-cli-service-names"></a>

**Admin Services**: Quorum authentication is used for admin privileged services like creating users, deleting users, changing user passwords, setting quorum values, and deactivating quorum and MFA capabilities.

**Crypto User Services**: Quorum authentication is used for crypto-user privileged services associated with a specific key like signing with a key, sharing/unsharing a key, wrapping/unwrapping a key, and setting a key's attribute. The quorum value of an associated key is configured when the key is generated, imported, or unwrapped. The quorum value must be equal to or less than the number of users that the key is associated with, which includes users that the key is shared with and the key owner.

Each service type is further broken down into a qualifying service name, which contains a specific set of quorum supported service operations that can be performed.


****  

| Service name | Service type | Service operations | 
| --- | --- | --- | 
| user | Admin |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/key-quorum-auth-chsm-cli-service-names.html)  | 
| quorum | Admin |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/key-quorum-auth-chsm-cli-service-names.html)  | 
| cluster1 | Admin |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/key-quorum-auth-chsm-cli-service-names.html)  | 
| key-management | Crypto User |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/key-quorum-auth-chsm-cli-service-names.html)  | 
| key-usage | Crypto User |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/key-quorum-auth-chsm-cli-service-names.html)  | 

[1] Cluster service is exclusively available on hsm2m.medium

# Set up quorum authentication for AWS CloudHSM crypto-users using CloudHSM CLI
<a name="key-quorum-auth-chsm-cli-first-time"></a>

These topics describe how to configure your CloudHSM for quorum authentication by [crypto-users](understanding-users.md#crypto-user-chsm-cli). Perform these steps once during initial setup. For subsequent key management and usage, refer to [Key management and usage with quorum authentication enabled for AWS CloudHSM using CloudHSM CLI](key-quorum-auth-chsm-cli-crypto-user.md).

**Topics**
+ [Prerequisites](#key-quorum-crypto-user-prerequisites)
+ [Step 1. Create and register a key for signing](#key-quorum-crypto-user-create-and-register-key)
+ [Step 2. Set the key quorum values during key generation](#key-quorum-admin-set-quorum-minimum-value-chsm-cli)

## Prerequisites
<a name="key-quorum-crypto-user-prerequisites"></a>
+ Familiarity with the [CloudHSM CLI](cloudhsm_cli.md)

## Step 1. Create and register a key for signing
<a name="key-quorum-crypto-user-create-and-register-key"></a>

To use quorum authentication, each crypto-user must complete *all* of the following steps: 

**Topics**
+ [Create an RSA key pair](#key-mofn-key-pair-create-chsm-cli)
+ [Create a registration token](#key-mofn-registration-token-chsm-cli)
+ [Sign the unsigned registration token](#key-mofn-sign-registration-token-chsm-cli)
+ [Register the public key with the HSM](#key-mofn-register-key-chsm-cli)

### Create an RSA key pair
<a name="key-mofn-key-pair-create-chsm-cli"></a>

There are many different ways to create and protect a key pair. The following examples show how to do it with [OpenSSL](https://www.openssl.org/).

**Example – Create a private key with OpenSSL**  
The following example demonstrates how to use OpenSSL to create a 2048-bit RSA key. To use this example, replace *<crypto\$1user1.key>* with the name of the file where you want to store the key.  

```
$ openssl genrsa -out <crypto_user1.key>
Generating RSA private key, 2048 bit long modulus
.....................................+++
.+++
e is 65537 (0x10001)
```

Next, generate the public key using the private key that you just created.

**Example – Create a public key with OpenSSL**  
The following example demonstrates how to use OpenSSL to create a public key from the private key you just created.  

```
$ openssl rsa -in crypto_user1.key -outform PEM -pubout -out crypto_user1.pub
writing RSA key
```

### Create a registration token
<a name="key-mofn-registration-token-chsm-cli"></a>

You create a token and sign it with the private key you just generated in the previous step.

**Create a registration token**

1. Use the following command to start the CloudHSM CLI:

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

   ```
   $ /opt/cloudhsm/bin/cloudhsm-cli interactive
   ```

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

   ```
   PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\cloudhsm-cli.exe" interactive
   ```

------

1. Create a registration token by running the [quorum token-sign generate](cloudhsm_cli-qm-token-gen.md) command:

   ```
   aws-cloudhsm > quorum token-sign generate --service registration --token /path/tokenfile
   {
     "error_code": 0,
     "data": {
       "path": "/path/tokenfile"
     }
   }
   ```

1. The [quorum token-sign generate](cloudhsm_cli-qm-token-gen.md) command generates a registration token at the specified file path. Inspect the token file:

   ```
   $ cat /path/tokenfile
   {
     "version": "2.0",
     "tokens": [
       {
         "approval_data": <approval data in base64 encoding>,
         "unsigned": <unsigned token in base64 encoding>,
         "signed": ""
       }
     ]
   }
   ```

   The token file consists of the following:
   + **approval\$1data**: A base64 encoded randomized data token whose raw data doesn’t exceed the maximum of 245 bytes.
   + **unsigned**: A base64 encoded and SHA256 hashed token of the approval\$1data.
   + **signed**: A base64 encoded signed token (signature) of the unsigned token, using the RSA 2048-bit private key previously generated with OpenSSL.

   You sign the unsigned token with the private key to demonstrate that you have access to the private key. You will need the registration token file fully populated with a signature and the public key to register the crypto-user as a quorum user with the AWS CloudHSM cluster.

### Sign the unsigned registration token
<a name="key-mofn-sign-registration-token-chsm-cli"></a>

1. Decode the base64 encoded unsigned token and place it into a binary file:

   ```
   $ echo -n '6BMUj6mUjjko6ZLCEdzGlWpR5sILhFJfqhW1ej3Oq1g=' | base64 -d > crypto_user.bin
   ```

1. Use OpenSSL and the private key to sign the now binary unsigned registration token and create a binary signature file:

   ```
   $ openssl pkeyutl -sign \
   -inkey crypto_user1.key \
   -pkeyopt digest:sha256 \
   -keyform PEM \
   -in crypto_user.bin \
   -out crypto_user.sig.bin
   ```

1. Encode the binary signature into base64:

   ```
   $ base64 -w0 crypto_user.sig.bin > crypto_user.sig.b64
   ```

1. Copy and paste the base64 encoded signature into the token file:

   ```
   {
     "version": "2.0",
     "tokens": [
       {
         "approval_data": <approval data in base64 encoding>,
         "unsigned": <unsigned token in base64 encoding>,
         "signed": <signed token in base64 encoding>
       }
     ]
   }
   ```

### Register the public key with the HSM
<a name="key-mofn-register-key-chsm-cli"></a>

After creating a key, the crypto-user must register the public key with the AWS CloudHSM cluster.

1. Start CloudHSM CLI:

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

   ```
   $ /opt/cloudhsm/bin/cloudhsm-cli interactive
   ```

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

   ```
   PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\cloudhsm-cli.exe" interactive
   ```

------

1. Sign in as the crypto-user whose public key you want to register.

   ```
   aws-cloudhsm > login --username crypto_user1 --role crypto-user
   Enter password:
   {
     "error_code": 0,
     "data": {
       "username": "crypto_user1",
       "role": "crypto-user"
     }
   }
   ```

1. Register the public key with the **[Register a user's token-sign quorum strategy using CloudHSM CLI](cloudhsm_cli-user-chqm-token-reg.md)**. For more information, see the following example or use the **help user change-quorum token-sign register** command.  
**Example – Register a public key with AWS CloudHSM cluster**  

   The following example shows how to use the **user change-quorum token-sign register** command in CloudHSM CLI to register a crypto-user public key with the HSM. To use this command, the crypto-user must be logged in to the HSM. Replace these values with your own:

   ```
   aws-cloudhsm > user change-quorum token-sign register --public-key </path/crypto_user.pub> --signed-token </path/tokenfile>
   {
     "error_code": 0,
     "data": {
       "username": "crypto_user1",
       "role": "crypto-user"
     }
   }
   ```
**Note**  
**/path/crypto\$1user.pub**: The filepath to the public key PEM file  
**Required**: Yes  
**/path/token\$1file**: The filepath with token signed by user private key  
**Required**: Yes

1. After all crypto-users register their public keys, the output from the **user list** command shows this in the quorum field, stating the enabled quorum strategy in use.

    In this example, the AWS CloudHSM cluster has two HSMs, each with the same crypto-users, as shown in the following output from the **user list** command. For more information about creating users, see [User management with CloudHSM CLI](manage-hsm-users-chsm-cli.md).

   ```
   aws-cloudhsm > user list
   {
     "error_code": 0,
     "data": {
       "users": [
         {
           "username": "admin",
           "role": "admin",
           "locked": "false",
           "mfa": [],
           "quorum": [],
           "cluster-coverage": "full"
         },
         {
           "username": "crypto_user1",
           "role": "crypto-user",
           "locked": "false",
           "mfa": [],
           "quorum": [
             {
               "strategy": "token-sign",
               "status": "enabled"
             }
           ],
           "cluster-coverage": "full"
         },
         {
           "username": "crypto_user2",
           "role": "crypto-user",
           "locked": "false",
           "mfa": [],
           "quorum": [
             {
               "strategy": "token-sign",
               "status": "enabled"
             }
           ],
           "cluster-coverage": "full"
         },
         {
           "username": "crypto_user3",
           "role": "crypto-user",
           "locked": "false",
           "mfa": [],
           "quorum": [
             {
               "strategy": "token-sign",
               "status": "enabled"
             }
           ],
           "cluster-coverage": "full"
         },
         {
           "username": "app_user",
           "role": "internal(APPLIANCE_USER)",
           "locked": "false",
           "mfa": [],
           "quorum": [],
           "cluster-coverage": "full"
         }
       ]
     }
   }
   ```

## Step 2. Set the key quorum values during key generation
<a name="key-quorum-admin-set-quorum-minimum-value-chsm-cli"></a>

To use quorum authentication, a crypto-user must log in to the HSM and then set the associated *key quorum values*. This is the minimum number of crypto-user approvals that are required to perform HSM key management/usage operations. For more information about the associated key commands associated with either key management or key usage, see [Supported services and types](key-quorum-auth-chsm-cli-service-names.md).

**Generate a key pair with key quorum values set**

1. Use the following command to start CloudHSM CLI:

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

   ```
   $ /opt/cloudhsm/bin/cloudhsm-cli interactive
   ```

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

   ```
   PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\cloudhsm-cli.exe" interactive
   ```

------

1. Using CloudHSM CLI, log in as a crypto-user.

   ```
   aws-cloudhsm > login --username crypto_user1 --role crypto-user
   Enter password:
   {
     "error_code": 0,
     "data": {
       "username": "crypto_user1",
       "role": "crypto-user"
     }
   }
   ```

This example generates an RSA key pair which has key quorum values of two (2) set for both key-management and key-usage operations. You can choose any value from zero (0) to eight (8), up to the total number of crypto-users on the HSM. In this example, the HSM has three (3) crypto-users, so the maximum possible value is three (3). Note that in this example we are sharing the key with *<crypto\$1user2>* during key generation. Also note that public keys do not have quorum values.

```
aws-cloudhsm > key generate-asymmetric-pair rsa \
--public-exponent 65537 \
--modulus-size-bits 2048 \
--public-label rsa-public-key-example \
--private-label rsa-private-key-example \
--public-attributes verify=true \
--private-attributes sign=true
--share-crypto-users crypto_user2 \
--manage-private-key-quorum-value 2 \
--use-private-key-quorum-value 2
{
  "error_code": 0,
  "data": {
    "public_key": {
      "key-reference": "0x0000000000640006",
      "key-info": {
        "key-owners": [
          {
            "username": "crypto_user",
            "key-coverage": "full"
          }
        ],
        "shared-users": [],
        "key-quorum-values": {
          "manage-key-quorum-value": 0,
          "use-key-quorum-value": 0
        },
        "cluster-coverage": "full"
      },
      "attributes": {
        "key-type": "rsa",
        "label": "rsa-public-key-example",
        "id": "0x",
        "check-value": "0x218f50",
        "class": "public-key",
        "encrypt": false,
        "decrypt": false,
        "token": true,
        "always-sensitive": false,
        "derive": false,
        "destroyable": true,
        "extractable": true,
        "local": true,
        "modifiable": true,
        "never-extractable": false,
        "private": true,
        "sensitive": false,
        "sign": false,
        "trusted": false,
        "unwrap": false,
        "verify": true,
        "wrap": false,
        "wrap-with-trusted": false,
        "key-length-bytes": 512,
        "public-exponent": "0x010001",
        "modulus": "0xbdf471a3d2a869492f51c767bece8780730ae6479a9a75efffe7cea3594fb28ca518630e7b1d988b45d2fedc830b7ab848448c24c476cacb73d1523278aed289551e07af0fbfabe4811cc4601678bd097b5c0a578249ed1eb0e4878a80ba1ed85ac46eb1fee60d2a8bdd322075196dec4b57fa2cd82af44ad068115ac219bc073ec65c19c97bd883cf26931408d7bc51e237626b8b9b8f2485425907a0eb42f2f4c40018c8dac7ceeb1b646305a2e537ab904346883e41d568264abee0137048e4657d2cf72801810f3212f662b7a7ae134848b922771f6a30aa76718008d9cc74ff8ddcd8d867b05c3d40020d1514999af96889911467191b9f390d8de07f83",
        "modulus-size-bits": 2048
      }
    },
    "private_key": {
      "key-reference": "0x0000000000640007",
      "key-info": {
        "key-owners": [
          {
            "username": "crypto_user",
            "key-coverage": "full"
          }
        ],
        "shared-users": [
          {
            "username": "crypto_user2",
            "key-coverage": "full"
          }
        ],
        "key-quorum-values": {
          "manage-key-quorum-value": 2,
          "use-key-quorum-value": 2
        },
        "cluster-coverage": "full"
      },
      "attributes": {
        "key-type": "rsa",
        "label": "rsa-private-key-example",
        "id": "0x",
        "check-value": "0x218f50",
        "class": "private-key",
        "encrypt": false,
        "decrypt": false,
        "token": true,
        "always-sensitive": true,
        "derive": false,
        "destroyable": true,
        "extractable": true,
        "local": true,
        "modifiable": true,
        "never-extractable": false,
        "private": true,
        "sensitive": true,
        "sign": true,
        "trusted": false,
        "unwrap": false,
        "verify": false,
        "wrap": false,
        "wrap-with-trusted": false,
        "key-length-bytes": 1216,
        "public-exponent": "0x010001",
        "modulus": "0xbdf471a3d2a869492f51c767bece8780730ae6479a9a75efffe7cea3594fb28ca518630e7b1d988b45d2fedc830b7ab848448c24c476cacb73d1523278aed289551e07af0fbfabe4811cc4601678bd097b5c0a578249ed1eb0e4878a80ba1ed85ac46eb1fee60d2a8bdd322075196dec4b57fa2cd82af44ad068115ac219bc073ec65c19c97bd883cf26931408d7bc51e237626b8b9b8f2485425907a0eb42f2f4c40018c8dac7ceeb1b646305a2e537ab904346883e41d568264abee0137048e4657d2cf72801810f3212f662b7a7ae134848b922771f6a30aa76718008d9cc74ff8ddcd8d867b05c3d40020d1514999af96889911467191b9f390d8de07f83",
        "modulus-size-bits": 2048
      }
    }
  }
}
```

When generating a key with quorum controls, the key must be associated with a minimum number of users equal to the largest key quorum value. Associated users include the key owner and Crypto Users with whom the key is shared with. To determine the number of minimum users to share the key with, get the largest quorum value between the key usage quorum value and the key management quorum value and subtract 1 to account for the key owner, who is by default associated with the key. To share the key with more users, use the **[Share a key using CloudHSM CLI](cloudhsm_cli-key-share.md)** command.

Failure to share the key with enough users at key generation will result in failure, as shown below.

```
aws-cloudhsm > key generate-asymmetric-pair rsa \
--public-exponent 65537 \
--modulus-size-bits 2048 \
--public-label rsa-public-key-example \
--private-label rsa-private-key-example \
--public-attributes verify=true \
--private-attributes sign=true
--share-crypto-users crypto_user2 crypto_user3 \
--manage-private-key-quorum-value 3 \
--use-private-key-quorum-value 4
{
  "error_code": 1,
  "data": "Invalid quorum value provided."
}
```

# Key management and usage with quorum authentication enabled for AWS CloudHSM using CloudHSM CLI
<a name="key-quorum-auth-chsm-cli-crypto-user"></a>

After you configure quorum authentication for your AWS CloudHSM cluster, crypto users can't perform HSM key management or usage operations on their own if their key has associated quorum values. This topic explains how a crypto-user can get a temporary token to perform an HSM key management or key usage operation.

**Note**  
Each quorum token is valid for one operation. When that operation succeeds, the token is no longer valid and the crypto-user must obtain a new token. A quorum token is only valid during your current login session. If you log out of the CloudHSM CLI or if the network disconnects, the token is no longer valid and you need to get a new token. You can only use a CloudHSM token within the CloudHSM CLI. You can't use it to authenticate in a different application.

The following example shows the output when a crypto-user tries to create a signature with a quorum-associated key on the HSM after quorum authentication is configured. The command fails with a `Quorum Failed` error, which means quorum authentication failed:

```
aws-cloudhsm > crypto sign rsa-pkcs --key-filter attr.label=rsa-private-key-example --hash-function sha256 --data YWJjMTIz
{
  "error_code": 1,
  "data": "Quorum Failed"
}
```

A crypto-user must complete the following tasks to get a temporary token for performing a key management or key usage operation on the HSM:

**Topics**
+ [Step 1. Get a quorum token](#key-quorum-admin-gen-token-chsm-cli)
+ [Step 2. Get signatures from approving crypto-users](#key-quorum-crypto-user-get-approval-signatures-chsm-cli)
+ [Step 3. Approve the token on the CloudHSM; cluster and execute an operation](#key-quorum-crypto-user-approve-token-chsm-cli)

## Step 1. Get a quorum token
<a name="key-quorum-admin-gen-token-chsm-cli"></a>

1. Start CloudHSM CLI.

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

   ```
   $ /opt/cloudhsm/bin/cloudhsm-cli interactive
   ```

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

   ```
   PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\cloudhsm-cli.exe" interactive
   ```

------

1. Log in to the cluster as a crypto-user.

   ```
   aws-cloudhsm > login --username <crypto_user1> --role crypto-user --password password123
   ```

   This example signs `crypto_user1` into the CloudHSM CLI with the `crypto-user` role. Replace these values with your own.

   ```
   {
     "error_code": 0,
     "data": {
       "username": "crypto_user1",
       "role": "crypto-user"
     }
   }
   ```

1. Generate a quorum token using the **quorum token-sign generate** command.

   In the following command, `key-usage` identifies the *service name* where you will use token that you are generating. In this case, the token is for key-usage operations (`key-usage` service) This example uses the `--filter` flag to associate the token with a specific key.

   ```
   aws-cloudhsm > quorum token-sign generate --service key-usage --token </path/crypto_user1.token> --filter attr.label=rsa-private-key-example
   {
     "error_code": 0,
     "data": {
       "path": "/home/crypto_user1.token"
     }
   }
   ```

   This example gets a quorum token for the crypto-user with username `crypto_user1` and saves the token to a file named `crypto_user1.token`. To use the example command, replace these values with your own:

   The **quorum token-sign generate** command generates a key-usage service quorum token at the specified file path. You can inspect the token file:

   ```
   $ cat </path/crypto_user1.token>
   {
     "version": "2.0",
     "service": "key-usage",
     "key_reference": "0x0000000000680006",
     "approval_data": "AAIABQAAABkAAAAAAGgABi5CDa9x9VyyRIaFbkSrHgJjcnlwdG9fdXNlcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnPQBLAAAAAAAAAAAAAgAFAAAAGgAAAAAAaAAGQvd2qKY+GJj8gXo9lKuANGNyeXB0b191c2VyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGc9AEsAAAAAAAAAAA==",
     "token": "5GlgoWOlQU4fw4QIlbxkPGZVOVoDugFGuSKE/k67ncM=",
     "signatures": []
   }
   ```

   The token file consists of the following:
   + **service**: An identifier for the quorum service the token is associated with.
   + **key\$1reference**: An identifier for the key that this quorum token is associated with.
   + **approval\$1data**: A base64 encoded raw data token generated by the HSM.
   + **token**: A base64 encoded and SHA-256 hashed token of the approval\$1data
   + **signatures**: An array of base64 encoded signed tokens (signatures) of the unsigned token. Each approver signature is in the form of a JSON object literal: 

     ```
     {
           "username": "<APPROVER_USERNAME>",
           "role": "<APPROVER_ROLE>",
           "signature": "<APPROVER_RSA2048_BIT_SIGNATURE>"
     }
     ```

     Each signature is created from the result of an approver using their corresponding RSA 2048-bit private key whose public key was registered with the HSM.

1. Validate the new user service quorum token. The **quorum token-sign list** command confirms that the token exists on CloudHSM.

   ```
   aws-cloudhsm > quorum token-sign list
   {
     "error_code": 0,
     "data": {
       "tokens": [
         {
           "username": "crypto_user",
           "service": "key-usage",
           "key-reference": "0x0000000000680006",
           "minimum-token-count": 2
         }
       ]
     }
   }
   ```

   The `minimum-token-count` presents an aggregated cluster view of the minimum usable number of key tokens corresponding to the username, service, and key-reference that are retrieved from a single HSM in the cluster.

   For example, assuming a 2-HSM cluster, if we receive two (2) key-usage tokens generated by user `crypto_user1` for key with reference `0x0000000000680006` from the first HSM in the cluster and we receive one (1) key-usage tokens generated by user `crypto_user1` for key with reference `0x0000000000680006` from the other HSM in the cluster, we will display `"minimum-token-count": 1`.

## Step 2. Get signatures from approving crypto-users
<a name="key-quorum-crypto-user-get-approval-signatures-chsm-cli"></a>

An crypto user who has a quorum token must get the token approved by other crypto-users. To give their approval, the other crypto =-users use their signing key to cryptographically sign the token outside the HSM.

There are many different ways to sign the token. The following example shows how to sign the token using [OpenSSL](https://www.openssl.org/). To use a different signing tool, make sure that the tool uses the private key (signing key) of the crypto-user to sign a SHA-256 digest of the token.

In this example, the crypto-user that has the token (`crypto-user`) needs at least two (2) approvals. The following example commands show how two (2) crypto-users can use OpenSSL to cryptographically sign the token.

1. Decode the base64 encoded unsigned token and place it into a binary file:

   ```
   $echo -n '5GlgoWOlQU4fw4QIlbxkPGZVOVoDugFGuSKE/k67ncM=' | base64 -d > crypto_user1.bin
   ```

1. Use OpenSSL and the approver's private key to sign the binary quorum unsigned token for the user service and create a binary signature file:

   ```
   $openssl pkeyutl -sign \
   -inkey crypto_user1.key \
   -pkeyopt digest:sha256 \
   -keyform PEM \
   -in crypto_user1.bin \
   -out crypto_user1.sig.bin
   ```

1. Encode the binary signature into base64:

   ```
   $ base64 -w0 crypto_user1.sig.bin > crypto_user1.sig.b64
   ```

1. Copy and paste the base64 encoded signature into the token file, using the JSON object literal format specified earlier for approver signature:

   ```
   {
     "version": "2.0",
     "service": "key-usage",
     "key_reference": "0x0000000000680006",
     "approval_data": "AAIABQAAABkAAAAAAGgABi5CDa9x9VyyRIaFbkSrHgJjcnlwdG9fdXNlcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnPQBLAAAAAAAAAAAAAgAFAAAAGgAAAAAAaAAGQvd2qKY+GJj8gXo9lKuANGNyeXB0b191c2VyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGc9AEsAAAAAAAAAAA==",
     "token": "5GlgoWOlQU4fw4QIlbxkPGZVOVoDugFGuSKE/k67ncM=",
     "signatures": [
       {
         "username": "crypto_user1",
         "role": "crypto-user",
         "signature": "wa7aPzmGwBjcEoZ6jAzYASp841AfgOvcI27Y/tGlCj1E9DawnFw5Uf0IJT2Ca7T5XD2ThVkUi0B+dhAomdqYNl6aUUFrJyH9GBJ+E0PmA5jNVm25tzeRWBJzneTg4/zTeE2reNqrHFHicWnttQLe9jS09J1znuDGWDe0HaBKWUaz2gUInJRqmeXDsZYdSvZksrqUH5dci/RsaDE2+tGiS9g0RcIkFbsPW4HpGe2e5HVzGsqrV8O3PKlYQv6+fymfcNTTuoxKcHAkOjpl43QSuSIu2gVq7KI8mSmmWaPJL47NPjmcBVB5vdEQU+oiukaNfLJr+MoDKzAvCGDg4cDArg=="
       },
       {
         "username": "crypto_user2",
         "role": "crypto-user",
         "signature": "wa7aPzmGwBjcEoZ6jAzYASp841AfgOvcI27Y/tGlCj1E9DawnFw5Uf0IJT2Ca7T5XD2ThVkUi0B+dhAomdqYNl6aUUFrJyH9GBJ+E0PmA5jNVm25tzeRWBJzneTg4/zTeE2reNqrHFHicWnttQLe9jS09J1znuDGWDe0HaBKWUaz2gUInJRqmeXDsZYdSvZksrqUH5dci/RsaDE2+tGiS9g0RcIkFbsPW4HpGe2e5HVzGsqrV8O3PKlYQv6+fymfcNTTuoxKcHAkOjpl43QSuSIu2gVq7KI8mSmmWaPJL47NPjmcBVB5vdEQU+oiukaNfLJr+MoDKzAvCGDg4cDArg=="
       }
     ]
   }
   ```

## Step 3. Approve the token on the CloudHSM; cluster and execute an operation
<a name="key-quorum-crypto-user-approve-token-chsm-cli"></a>

After a crypto-user has the necessary approvals and signatures, they can supply that token to the CloudHSM cluster along with a key management or key usage operation. 

Make sure the key operation corresponds to the appropriate quorum service associated with the quorum token. For more information, see [Supported services and types](key-quorum-auth-chsm-cli-service-names.md) for more information.

During the transaction, the token will be approved within the AWS CloudHSM cluster and execute the requested key operation. The success of the key operation is contingent upon both a valid approved quorum token and a valid key operation.

**Example Generate a signature with the RSA-PKCS mechanism**  
In the following example, a logged in crypto-user creates a signature with a key on the HSM:  

```
aws-cloudhsm > crypto sign rsa-pkcs --key-filter attr.label=rsa-private-key-example --hash-function sha256 --data YWJjMTIz --approval /path/crypto_user1.token
      
{
  "error_code": 0,
  "data": {
    "key-reference": "0x0000000000640007",
    "signature": "h6hMqXacBrT3x3MXV13RXHdQno0+IQ6iy0kVrGzo23+eoWT0ZZgrSpBCu5KcuP6IYYHw9goQ5CfPf4jI1nO5m/IUJtF1A1lmcz0HjEy1CJ7ICXNReDRyeOU8m43dkJzt0OUdkbtkDJGAcxkbKHLZ02uWsGXaQ8bOKhoGwsRAHHF6nldTXquICfOHgSd4nimObKTqzUkghhJW5Ot5oUyLMYP+pZmUS38ythybney94Wj6fzYOER8v7VIY5ijQGa3LfxrjSG4aw6QijEEbno5LSf18ahEaVKmVEnDBL54tylCJBGvGsYSY9HNhuJoHPgiDL/TDd2wfvP4PaxbFRyyHaw=="
  }
}
```
If the crypto user tries to perform another HSM key usage operation with the same token, it fails:  

```
aws-cloudhsm > crypto sign rsa-pkcs --key-filter attr.label=rsa-private-key-example --hash-function sha256 --data YWJjMTIz --approval /home/crypto_user1.token
{
  "error_code": 1,
  "data": "Quorum approval is required for this operation"
}
```
To perform another HSM key operation, the crypto user must generate a new quorum token, get new signatures from approvers, and execute the desired key operation with the --approval argument to supply the quorum token.  
Use the **quorum token-sign list** to check for available token. This example shows that the crypto-user has no approved tokens.   

```
aws-cloudhsm > quorum token-sign list
{
  "error_code": 0,
  "data": {
    "tokens": []
  }
}
```

# Key management with the AWS CloudHSM KMU
<a name="manage-keys-kmu-cmu"></a>

If using the [latest SDK version series](use-hsm.md), use [CloudHSM CLI](cloudhsm_cli.md) to manage the keys in your AWS CloudHSM cluster.

If using the [previous SDK version series](choose-client-sdk.md), you can manage keys on the hardware security modules (HSM) in your AWS CloudHSM cluster using the key\$1mgmt\$1util (KMU) command line tool. Before you can manage keys, you must start the AWS CloudHSM client, start key\$1mgmt\$1util, and log in to the HSMs. For more information, see [Getting Started with key\$1mgmt\$1util](key_mgmt_util-getting-started.md).
+ [Using trusted keys](cloudhsm_using_trusted_keys_control_key_wrap.md) describes how to use PKCS \$111 library attributes and CMU to create trusted keys to secure data.
+ [Generating keys](generate-keys.md) has instructions on generating keys, including symmetric keys, RSA keys, and EC keys.
+ [Importing keys](import-keys.md) provides details on how key owners import keys.
+ [Exporting keys](export-keys.md) provides details on how key owners export keys.
+ [Deleting keys](delete-keys.md) provides details on how key owners delete keys.
+ [Sharing and unsharing keys](share-keys.md) details how key owners share and unshare keys.

# Generate keys with the AWS CloudHSM KMU
<a name="generate-keys"></a>

To generate keys on the hardware security module (HSM), use the command in AWS CloudHSM key\$1mgmt\$1util (KMU) that corresponds to the type of key that you want to generate.

**Topics**
+ [Generate symmetric keys](generate-symmetric-keys.md)
+ [Generate RSA key pairs](generate-rsa-key-pairs.md)
+ [Generate ECC (elliptic curve cryptography) key pairs](generate-ecc-key-pairs.md)

# Generate symmetric keys with the AWS CloudHSM KMU
<a name="generate-symmetric-keys"></a>

Use the [genSymKey](key_mgmt_util-genSymKey.md) command in AWS CloudHSM key\$1mgmt\$1util (KMU) to generate AES and other types of symmetric keys for AWS CloudHSM. To see all available options, use the **genSymKey -h** command.

The following example creates a 256-bit AES key.

```
Command: genSymKey -t 31 -s 32 -l aes256
Cfm3GenerateSymmetricKey returned: 0x00 : HSM Return: SUCCESS

Symmetric Key Created.  Key Handle: 524295

Cluster Error Status
Node id 0 and err state 0x00000000 : HSM Return: SUCCESS
Node id 1 and err state 0x00000000 : HSM Return: SUCCESS
Node id 2 and err state 0x00000000 : HSM Return: SUCCESS
```

# Generate RSA key pairs with the AWS CloudHSM KMU
<a name="generate-rsa-key-pairs"></a>

To generate an RSA key pair for AWS CloudHSM, use the [genRSAKeyPair](key_mgmt_util-genRSAKeyPair.md) command in AWS CloudHSM key\$1mgmt\$1util. To see all available options, use the **genRSAKeyPair -h** command.

The following example generates an RSA 2048-bit key pair.

```
Command: genRSAKeyPair -m 2048 -e 65537 -l rsa2048
Cfm3GenerateKeyPair returned: 0x00 : HSM Return: SUCCESS

Cfm3GenerateKeyPair:    public key handle: 524294    private key handle: 524296

Cluster Error Status
Node id 0 and err state 0x00000000 : HSM Return: SUCCESS
Node id 1 and err state 0x00000000 : HSM Return: SUCCESS
Node id 2 and err state 0x00000000 : HSM Return: SUCCESS
```

# Generate ECC (elliptic curve cryptography) key pairs using the AWS CloudHSM KMU
<a name="generate-ecc-key-pairs"></a>

To generate an ECC key pair for AWS CloudHSM, use the [genECCKeyPair](key_mgmt_util-genECCKeyPair.md) command in AWS CloudHSM key\$1mgmt\$1util. To see all available options, including a list of the supported elliptic curves, use the **genECCKeyPair -h** command.

The following example generates an ECC key pair using the P-384 elliptic curve defined in [NIST FIPS publication 186-4](http://dx.doi.org/10.6028/NIST.FIPS.186-4).

```
Command: genECCKeyPair -i 14 -l ecc-p384
Cfm3GenerateKeyPair returned: 0x00 : HSM Return: SUCCESS

Cfm3GenerateKeyPair:    public key handle: 524297    private key handle: 524298

Cluster Error Status
Node id 0 and err state 0x00000000 : HSM Return: SUCCESS
Node id 1 and err state 0x00000000 : HSM Return: SUCCESS
Node id 2 and err state 0x00000000 : HSM Return: SUCCESS
```

# Import keys with the AWS CloudHSM KMU
<a name="import-keys"></a>

To import secret keys—that is, symmetric keys and asymmetric private keys—into the hardware security module (HSM) using the AWS CloudHSM key\$1mgmt\$1util, you must first create a wrapping key on the HSM. You can import public keys directly without a wrapping key.

**Topics**
+ [Import secret keys](import-secret-keys.md)
+ [Import public keys](import-public-keys.md)

# Import secret keys with the AWS CloudHSM KMU
<a name="import-secret-keys"></a>

Complete the following steps to import a secret key into AWS CloudHSM using the key\$1mgmt\$1util (KMU). Before you import a secret key, save it to a file. Save symmetric keys as raw bytes, and asymmetric private keys in PEM format.

This example shows how to import a plaintext secret key from a file into the HSM. To import an encrypted key from a file into the HSM, use the [unWrapKey](key_mgmt_util-unwrapKey.md) command.

**To import a secret key**

1. Use the [genSymKey](key_mgmt_util-genSymKey.md) command to create a wrapping key. The following command creates a 128-bit AES wrapping key that is valid only for the current session. You can use a session key or a persistent key as a wrapping key.

   ```
   Command: genSymKey -t 31 -s 16 -sess -l import-wrapping-key
   Cfm3GenerateSymmetricKey returned: 0x00 : HSM Return: SUCCESS
   
   Symmetric Key Created.  Key Handle: 524299
   
   Cluster Error Status
   Node id 2 and err state 0x00000000 : HSM Return: SUCCESS
   ```

1. Use one of the following commands, depending on the type of secret key that you are importing.
   + To import a symmetric key, use the [imSymKey](key_mgmt_util-imSymKey.md) command. The following command imports an AES key from a file named `aes256.key` using the wrapping key created in the previous step. To see all available options, use the **imSymKey -h** command.

     ```
     Command: imSymKey -f aes256.key -t 31 -l aes256-imported -w 524299
     Cfm3WrapHostKey returned: 0x00 : HSM Return: SUCCESS
     
     Cfm3CreateUnwrapTemplate returned: 0x00 : HSM Return: SUCCESS
     
     Cfm3UnWrapKey returned: 0x00 : HSM Return: SUCCESS
     
     Symmetric Key Unwrapped.  Key Handle: 524300
     
     Cluster Error Status
     Node id 0 and err state 0x00000000 : HSM Return: SUCCESS
     Node id 1 and err state 0x00000000 : HSM Return: SUCCESS
     Node id 2 and err state 0x00000000 : HSM Return: SUCCESS
     ```
   + To import an asymmetric private key, use the [importPrivateKey](key_mgmt_util-importPrivateKey.md) command. The following command imports a private key from a file named `rsa2048.key` using the wrapping key created in the previous step. To see all available options, use the **importPrivateKey -h** command.

     ```
     Command: importPrivateKey -f rsa2048.key -l rsa2048-imported -w 524299
     BER encoded key length is 1216
     
     Cfm3WrapHostKey returned: 0x00 : HSM Return: SUCCESS
     
     Cfm3CreateUnwrapTemplate returned: 0x00 : HSM Return: SUCCESS
     
     Cfm3UnWrapKey returned: 0x00 : HSM Return: SUCCESS
     
     Private Key Unwrapped.  Key Handle: 524301
     
     Cluster Error Status
     Node id 0 and err state 0x00000000 : HSM Return: SUCCESS
     Node id 1 and err state 0x00000000 : HSM Return: SUCCESS
     Node id 2 and err state 0x00000000 : HSM Return: SUCCESS
     ```

# Import public keys with the AWS CloudHSM KMU
<a name="import-public-keys"></a>

Use the [importPubKey](key_mgmt_util-importPubKey.md) command in the AWS CloudHSM key\$1mgmt\$1util (KMU) to import a public key. To see all available options, use the **importPubKey -h** command.

The following example imports an RSA public key from a file named `rsa2048.pub`.

```
Command: importPubKey -f rsa2048.pub -l rsa2048-public-imported
Cfm3CreatePublicKey returned: 0x00 : HSM Return: SUCCESS

Public Key Handle: 524302

Cluster Error Status
Node id 0 and err state 0x00000000 : HSM Return: SUCCESS
Node id 1 and err state 0x00000000 : HSM Return: SUCCESS
Node id 2 and err state 0x00000000 : HSM Return: SUCCESS
```

# Export keys with the AWS CloudHSM KMU
<a name="export-keys"></a>

To export AWS CloudHSM secret keys—that is, symmetric keys and asymmetric private keys—from the hardware security module (HSM) using the AWS CloudHSM key\$1mgmt\$1util (KMU), you must first create a wrapping key. You can export public keys directly without a wrapping key. 

Only the key owner can export a key. Users with whom the key is shared can use the key in cryptographic operations, but they cannot export it. When running this example, be sure to export a key that you created. 

**Important**  
The [exSymKey](key_mgmt_util-exSymKey.md) command writes a plaintext (unencrypted) copy of the secret key to a file. The export process requires a wrapping key, but the key in the file is ***not*** a wrapped key. To export a wrapped (encrypted) copy of a key, use the [wrapKey](key_mgmt_util-wrapKey.md) command.

**Topics**
+ [Export secret keys](export-secret-keys.md)
+ [Export public keys](export-public-keys.md)

# Export secret keys with the AWS CloudHSM KMU
<a name="export-secret-keys"></a>

Complete the following steps to export a secret key from AWS CloudHSM using the key\$1mgmt\$1util (KMU). 

**To export a secret key**

1. Use the [genSymKey](key_mgmt_util-genSymKey.md) command to create a wrapping key. The following command creates a 128-bit AES wrapping key that is valid only for the current session.

   ```
   Command: genSymKey -t 31 -s 16 -sess -l export-wrapping-key
   Cfm3GenerateSymmetricKey returned: 0x00 : HSM Return: SUCCESS
   
   Symmetric Key Created.  Key Handle: 524304
   
   Cluster Error Status
   Node id 2 and err state 0x00000000 : HSM Return: SUCCESS
   ```

1. Use one of the following commands, depending on the type of secret key that you are exporting.
   + To export a symmetric key, use the [exSymKey](key_mgmt_util-exSymKey.md) command. The following command exports an AES key to a file named `aes256.key.exp`. To see all available options, use the **exSymKey -h** command.

     ```
     Command: exSymKey -k 524295 -out aes256.key.exp -w 524304
     Cfm3WrapKey returned: 0x00 : HSM Return: SUCCESS
     
     Cfm3UnWrapHostKey returned: 0x00 : HSM Return: SUCCESS
     
     
     Wrapped Symmetric Key written to file "aes256.key.exp"
     ```
**Note**  
The command's output says that a "Wrapped Symmetric Key" is written to the output file. However, the output file contains a plaintext (not wrapped) key. To export a wrapped (encrypted) key to a file, use the [wrapKey](key_mgmt_util-wrapKey.md) command.
   + To export a private key, use the **exportPrivateKey** command. The following command exports a private key to a file named `rsa2048.key.exp`. To see all available options, use the **exportPrivateKey -h** command.

     ```
     Command: exportPrivateKey -k 524296 -out rsa2048.key.exp -w 524304
     Cfm3WrapKey returned: 0x00 : HSM Return: SUCCESS
     
     Cfm3UnWrapHostKey returned: 0x00 : HSM Return: SUCCESS
     
     PEM formatted private key is written to rsa2048.key.exp
     ```

# Export public keys with the AWS CloudHSM KMU
<a name="export-public-keys"></a>

Use the **exportPubKey** command in the AWS CloudHSM key\$1mgmt\$1util (KMU) to export a public key. To see all available options, use the **exportPubKey -h** command.

The following example exports an RSA public key to a file named `rsa2048.pub.exp`.

```
Command: exportPubKey -k 524294 -out rsa2048.pub.exp
PEM formatted public key is written to rsa2048.pub.key

Cfm3ExportPubKey returned: 0x00 : HSM Return: SUCCESS
```

# Delete keys with KMU and CMU
<a name="delete-keys"></a>

Use the [deleteKey](key_mgmt_util-deleteKey.md) command to delete a key, as in the following example. Only the key owner can delete a key.

```
Command: deleteKey -k 524300
Cfm3DeleteKey returned: 0x00 : HSM Return: SUCCESS

Cluster Error Status
Node id 0 and err state 0x00000000 : HSM Return: SUCCESS
Node id 1 and err state 0x00000000 : HSM Return: SUCCESS
Node id 2 and err state 0x00000000 : HSM Return: SUCCESS
```

# Share and unshare keys with KMU and CMU
<a name="share-keys"></a>

In AWS CloudHSM, the CU who creates the key owns it. The owner manages the key, can export and delete it, and can use the key in cryptographic operations. The owner can also share the key with other CU users. Users with whom the key is shared can use the key in cryptographic operations, but they cannot export or delete the key, or share it with other users.

You can share keys with other CU users when you create the key, such as by using the `-u` parameter of the [genSymKey](key_mgmt_util-genSymKey.md) or [genRSAKeyPair](key_mgmt_util-genRSAKeyPair.md) commands. To share existing keys with a different HSM user, use the [cloudhsm\$1mgmt\$1util](cloudhsm_mgmt_util.md) command line tool. This is different from most of the tasks documented in this section, which use the [key\$1mgmt\$1util](key_mgmt_util.md) command line tool.

Before you can share a key, you must start cloudhsm\$1mgmt\$1util, enable end-to-end encryption, and log in to the HSMs. To share a key, log in to the HSM as the crypto user (CU) that owns the key. Only key owners can share a key.

Use the **shareKey** command to share or unshare a key, specifying the handle of the key and the IDs of the user or users. To share or unshare with more than one user, specify a comma-separated list of user IDs. To share a key, use `1` as the command's last parameter, as in the following example. To unshare, use `0`.

```
aws-cloudhsm > shareKey 524295 4 1
*************************CAUTION********************************
This is a CRITICAL operation, should be done on all nodes in the
cluster. AWS does NOT synchronize these changes automatically with the
nodes on which this operation is not executed or failed, please
ensure this operation is executed on all nodes in the cluster.
****************************************************************

Do you want to continue(y/n)? y
shareKey success on server 0(10.0.2.9)
shareKey success on server 1(10.0.3.11)
shareKey success on server 2(10.0.1.12)
```

The following shows the syntax for the **shareKey** command.

```
aws-cloudhsm > shareKey <key handle> <user ID> <Boolean: 1 for share, 0 for unshare>
```

# How to mark a key as trusted with the AWS CloudHSM Management Utility
<a name="cloudhsm_using_trusted_keys_control_key_wrap"></a>

The content in this section provides instructions on using the AWS CloudHSM management Utility (CMU) to mark a key as trusted.

1. Using the [loginHSM](cloudhsm_mgmt_util-loginLogout.md) command, log in as a crypto officer (CO).

1. Use the [Set the attributes of AWS CloudHSM keys using CMU](cloudhsm_mgmt_util-setAttribute.md) command with `OBJ_ATTR_TRUSTED` (value `134`) set to true (`1`).

   ```
   aws-cloudhsm > setAttribute <Key Handle> 134 1
   ```