

# Integrating third-party applications with AWS CloudHSM
<a name="third-party-applications"></a>

Some of the [use cases](use-cases.md) for AWS CloudHSM involve integrating third-party software applications with the HSM in your AWS CloudHSM cluster. By integrating third-party software with AWS CloudHSM, you can accomplish a variety of security-related goals. The following topics describe how to accomplish some of these goals. 

**Topics**
+ [SSL/TLS offload](ssl-offload.md)
+ [Windows Server CA](third-ca-toplevel.md)
+ [Oracle database encryption](oracle-tde.md)
+ [Microsoft SignTool](third-signtool-toplevel.md)
+ [Java Keytool and Jarsigner](third_java-sdk_integration.md)
+ [Microsoft Manifest Generation and Editing Tool](third-magetool.md)
+ [Other third-party vendor integrations](other-integrations.md)

# Improve your web server security with SSL/TLS offload in AWS CloudHSM
<a name="ssl-offload"></a>

Web servers and their clients (web browsers) can use Secure Sockets Layer (SSL) or Transport Layer Security (TLS) protocols to confirm the identity of the web server and establish a secure connection that sends and receives webpages or other data over the internet. This is commonly known as HTTPS. The web server uses a public–private key pair and an SSL/TLS public key certificate to establish an HTTPS session with each client. This process involves a lot of computation for web servers, but you can offload some of this to your AWS CloudHSM cluster, which is referred to as SSL acceleration. Offloading reduces the computational burden on your web servers and provides extra security by storing servers’ private keys in HSMs.

The following topics provide an overview of how SSL/TLS offload with AWS CloudHSM works and tutorials for setting up SSL/TLS offload with AWS CloudHSM on the following platforms.

For **Linux**, use OpenSSL Dynamic Engine on the [NGINX](https://nginx.org/en/) or [Apache HTTP Server](https://httpd.apache.org/) web server software

For **Windows**, use the [Internet Information Services (IIS) for Windows Server](https://www.iis.net/) web server software

**Topics**
+ [

# How SSL/TLS offload with AWS CloudHSM works
](ssl-offload-overview.md)
+ [

# AWS CloudHSM SSL/TLS offload on Linux using NGINX or Apache with OpenSSL
](third-offload-linux-openssl.md)
+ [

# AWS CloudHSM SSL/TLS offload on Linux using NGINX or HAProxy with OpenSSL Provider
](third-offload-linux-openssl-provider.md)
+ [

# AWS CloudHSM SSL/TLS offload on Linux using Tomcat with JSSE
](third-offload-linux-jsse.md)
+ [

# AWS CloudHSM SSL/TLS offload on Windows using IIS with KSP
](ssl-offload-windows.md)
+ [

# Add a load balancer with Elastic Load Balancing for AWS CloudHSM(optional)
](third-offload-add-lb.md)

# How SSL/TLS offload with AWS CloudHSM works
<a name="ssl-offload-overview"></a>

To establish an HTTPS connection, your web server performs a handshake process with clients. As part of this process, the server offloads some of the cryptographic processing to the HSMs in the AWS CloudHSM cluster, as shown in the following figure. Each step of the process is explained below the figure. 

**Note**  
The following image and process assumes that RSA is used for server verification and key exchange. The process is slightly different when Diffie–Hellman is used instead of RSA. 

![\[An illustration of the TLS handshake process between a client and server including cryptographic offload to an HSM.\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/ssl-offload-handshake-process.png)


1. The client sends a hello message to the server.

1. The server responds with a hello message and sends the server's certificate.

1. The client performs the following actions:

   1. Verifies that the SSL/TLS server certificate is signed by a root certificate that the client trusts. 

   1. Extracts the public key from the server certificate.

   1. Generates a pre-master secret and encrypts it with the server's public key.

   1. Sends the encrypted pre-master secret to the server.

1. To decrypt the client's pre-master secret, the server sends it to the HSM. The HSM uses the private key in the HSM to decrypt the pre-master secret and then it sends the pre-master secret to the server. Independently, the client and server each use the pre-master secret and some information from the hello messages to calculate a master secret. 

1. The handshake process ends. For the rest of the session, all messages sent between the client and the server are encrypted with derivatives of the master secret. 

To learn how to configure SSL/TLS offload with AWS CloudHSM, see one of the following topics:
+ [AWS CloudHSM SSL/TLS offload on Linux using NGINX or Apache with OpenSSL](third-offload-linux-openssl.md)
+ [AWS CloudHSM SSL/TLS offload on Linux using Tomcat with JSSE](third-offload-linux-jsse.md)
+ [AWS CloudHSM SSL/TLS offload on Windows using IIS with KSP](ssl-offload-windows.md)

# AWS CloudHSM SSL/TLS offload on Linux using NGINX or Apache with OpenSSL
<a name="third-offload-linux-openssl"></a>

This topic provides step-by-step instructions for setting up SSL/TLS offload with AWS CloudHSM on a Linux web server.

**Topics**
+ [

## Overview
](#ssl-offload-linux-openssl-overview)
+ [

## Step 1: Set up the prerequisites
](#ssl-offload-prerequisites)
+ [

## Step 2: Generate the private key and SSL/TLS certificate
](#ssl-offload-import-or-generate-private-key-and-certificate)
+ [

## Step 3: Configure the web server
](#ssl-offload-configure-web-server)
+ [

## Step 4: Enable HTTPS traffic and verify the certificate
](#ssl-offload-enable-traffic-and-verify-certificate)

## Overview
<a name="ssl-offload-linux-openssl-overview"></a>

On Linux, the [NGINX](https://nginx.org/en/) and [Apache HTTP Server](https://httpd.apache.org/) web server software integrate with [OpenSSL](https://www.openssl.org/) to support HTTPS. The [AWS CloudHSM dynamic engine for OpenSSL](openssl-library.md) provides an interface that enables the web server software to use the HSMs in your cluster for cryptographic offloading and key storage. The OpenSSL engine is the bridge that connects the web server to your AWS CloudHSM cluster.

To complete this tutorial, you must first choose whether to use the NGINX or Apache web server software on Linux. Then the tutorial shows you how to do the following:
+ Install the web server software on an Amazon EC2 instance.
+ Configure the web server software to support HTTPS with a private key stored in your AWS CloudHSM cluster.
+ (Optional) Use Amazon EC2 to create a second web server instance and Elastic Load Balancing to create a load balancer. Using a load balancer can increase performance by distributing the load across multiple servers. It can also provide redundancy and higher availability if one or more servers fail.

When you're ready to get started, go to [Step 1: Set up the prerequisites](#ssl-offload-prerequisites).

## Step 1: Set up the prerequisites
<a name="ssl-offload-prerequisites"></a>

Different platforms require different prerequisites. Use the prerequisites section below that matches your platform.

### Prerequisites for Client SDK 5
<a name="new-versions"></a>

To set up web server SSL/TLS offload with Client SDK 5, you need the following:
+ An active AWS CloudHSM cluster with at least two hardware security modules (HSM)
**Note**  
You can use a single HSM cluster, but you must first disable client key durability. For more information, see [Manage Client Key Durability Settings](working-client-sync.md#client-sync-sdk8) and [Client SDK 5 Configure Tool](configure-sdk-5.md).
+ An Amazon EC2 instance running a Linux operating system with the following software installed:
  + A web server (either NGINX or Apache)
  + The OpenSSL Dynamic Engine for Client SDK 5
+ A [crypto user](understanding-users.md#crypto-user-chsm-cli) (CU) to own and manage the web server's private key on the HSM.

**To set up a Linux web server instance and create a CU on the HSM**

1. Install and configure the OpenSSL Dynamic Engine for AWS CloudHSM. For more information about installing OpenSSL Dynamic Engine, see [OpenSSL Dynamic Engine for Client SDK 5](openssl5-install.md).

1. On an EC2 Linux instance that has access to your cluster, install either NGINX or Apache web server:

------
#### [ Amazon Linux 2 ]
   + For information on how to download the latest version of NGINX on Amazon Linux 2, see the [NGINX website](https://nginx.org/en/linux_packages.html).

     The latest version of NGINX available for Amazon Linux 2 uses a version of OpenSSL that is newer than the system version of OpenSSL. After installing NGINX, you need to create a symbolic link from the AWS CloudHSM OpenSSL Dynamic Engine library to the location that this version of OpenSSL expects 

     ```
     $ sudo ln -sf /opt/cloudhsm/lib/libcloudhsm_openssl_engine.so /usr/lib64/engines-1.1/cloudhsm.so
     ```
   + Apache

     ```
     $ sudo yum install httpd mod_ssl
     ```

------
#### [ Amazon Linux 2023 ]
   + NGINX

     ```
     $ sudo yum install nginx
     ```
   + Apache

     ```
     $ sudo yum install httpd mod_ssl
     ```

------
#### [ Red Hat 8 ]
   + NGINX

     ```
     $ sudo yum install nginx
     ```
   + Apache

     ```
     $ sudo yum install httpd mod_ssl
     ```

------
#### [ Red Hat 9 ]
   + NGINX

     ```
     $ sudo yum install nginx
     ```
   + Apache

     ```
     $ sudo yum install httpd mod_ssl
     ```

------
#### [ Ubuntu 22.04 ]
   + NGINX

     ```
     $ sudo apt install nginx
     ```
   + Apache

     ```
     $ sudo apt install apache2
     ```

------
#### [ Ubuntu 24.04 ]
   + NGINX

     ```
     $ sudo apt install nginx
     ```
   + Apache

     ```
     $ sudo apt install apache2
     ```

------

1. Use CloudHSM CLI to create a [crypto user](understanding-users.md#crypto-user-chsm-cli). For more information about managing HSM users, see [Managing HSM users with CloudHSM CLI](manage-hsm-users-chsm-cli.md).
**Tip**  
Keep track of the CU user name and password. You will need them later when you generate or import the HTTPS private key and certificate for your web server.

After you complete these steps, go to [Step 2: Generate the private key and SSL/TLS certificate](#ssl-offload-import-or-generate-private-key-and-certificate).

#### Notes
<a name="note-ssl5-pre"></a>
+ To use Security-Enhanced Linux (SELinux) and web servers, you must allow outbound TCP connections on port 2223, which is the port Client SDK 5 uses to communicate with the HSM.
+ To create and activate a cluster and give an EC2 instance access to the cluster, complete the steps in [Getting Started with AWS CloudHSM](getting-started.md). The getting started offers step-by-step instruction for creating an active cluster with one HSM and an Amazon EC2 client instance. You can use this client instance as your web server. 
+ To avoid disabling client key durability, add more than one HSM to your cluster. For more information, see [Adding an HSM to an AWS CloudHSM cluster](add-hsm.md).
+ To connect to your client instance, you can use SSH or PuTTY. For more information, see [Connecting to Your Linux Instance Using SSH](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html) or [Connecting to Your Linux Instance from Windows Using PuTTY](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html) in the Amazon EC2 documentation. 

## Step 2: Generate the private key and SSL/TLS certificate
<a name="ssl-offload-import-or-generate-private-key-and-certificate"></a>

To enable HTTPS, your web server application (NGINX or Apache) needs a private key and a corresponding SSL/TLS certificate. To use web server SSL/TLS offload with AWS CloudHSM, you must store the private key in an HSM in your AWS CloudHSM cluster. You will first generate a private key and use the key to create a certificate signing request (CSR). You then export a *fake PEM private key* from the HSM, which is a private key file in PEM format which contains a reference to the private key stored on the HSM (it's not the actual private key). Your web server uses the fake PEM private key file to identify the private key on the HSM during SSL/TLS offload.

### Generate a private key and certificate
<a name="ssl-offload-generate-private-key-and-certificate"></a>

#### Generate a private key
<a name="ssl-offload-generate-private-key"></a>

This section shows you how to generate a keypair using the [CloudHSM CLI](cloudhsm_cli.md). Once you have a key pair generated inside the HSM, you can export it as a fake PEM file and generate the corresponding certificate. <a name="ssl-offload-generate-private-key-prerequisites"></a>

**Install and configure the CloudHSM CLI**

1. [Install and Configure](cloudhsm_cli-getting-started.md) the CloudHSM CLI.

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

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

1. Run the following command to log in to the HSM. Replace *<user name>* with the user name of your crypto-user

   ```
   Command: login --username <user name> --role crypto-user
   ```

**Generate a Private Key**

Depending on your use case, you can either generate an RSA or an EC key pair. Do one of the following:
+ To generate an RSA private key on an HSM

  Use the [`key generate-asymmetric-pair rsa`](cloudhsm_cli-key-generate-asymmetric-pair-rsa.md) command to generate an RSA key pair. This example generates an RSA key pair with a modulus of 2048, a public exponent of 65537, public key label of *tls\$1rsa\$1pub*, and private key label of *tls\$1rsa\$1private*.

  ```
  aws-cloudhsm > key generate-asymmetric-pair rsa \
  --public-exponent 65537 \
  --modulus-size-bits 2048 \
  --public-label tls_rsa_pub \
  --private-label tls_rsa_private \
  --private-attributes sign=true
  {
    "error_code": 0,
    "data": {
      "public_key": {
        "key-reference": "0x0000000000280cc8",
        "key-info": {
          "key-owners": [
            {
              "username": "cu1",
              "key-coverage": "full"
            }
          ],
          "shared-users": [],
          "cluster-coverage": "full"
        },
        "attributes": {
          "key-type": "rsa",
          "label": "tls_rsa_pub",
          "id": "",
          "check-value": "0x01fe6e",
          "class": "public-key",
          "encrypt": true,
          "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": false,
          "wrap": false,
          "wrap-with-trusted": false,
          "key-length-bytes": 512,
          "public-exponent": "0x010001",
          "modulus": "0xb1d27e857a876f4e9fd5de748a763c539b359f937eb4b4260e30d1435485a732c878cdad9c72538e2215351b1d41358c9bf80b599c
  73a80fdb457aa7b20cd61e486c326e2cfd5e124a7f6a996437437812b542e3caf85928aa866f0298580f7967ee6aa01440297d7308fdd9b76b70d1b67f12634d
  f6e6296d6c116d5744c6d60d14d3bf3cb978fe6b75ac67b7089bafd50d8687213b31abc7dc1bad422780d29c851d5102b56f932551eaf52a9591fd8c43d81ecc
  133022653225bd129f8491101725e9ea33e1ded83fb57af35f847e532eb30cd7e726f23910d2671c6364092e834697ec3cef72cc23615a1ba7c5e100156ae0ac
  ac3160f0ca9725d38318b7",
          "modulus-size-bits": 2048
        }
      },
      "private_key": {
        "key-reference": "0x0000000000280cc7",
        "key-info": {
          "key-owners": [
            {
              "username": "cu1",
              "key-coverage": "full"
            }
          ],
          "shared-users": [],
          "cluster-coverage": "full"
        },
        "attributes": {
          "key-type": "rsa",
          "label": "tls_rsa_private",
          "id": "",
          "check-value": "0x01fe6e",
          "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": false,
          "verify": false,
          "wrap": false,
          "wrap-with-trusted": false,
          "key-length-bytes": 1217,
          "public-exponent": "0x010001",
          "modulus": "0xb1d27e857a876f4e9fd5de748a763c539b359f937eb4b4260e30d1435485a732c878cdad9c72538e2215351b1d41358c9bf80b599c73a80fdb457aa7b20cd61e486c326e2cfd5e124a7f6a996437437812b542e3caf85928aa866f0298580f7967ee6aa01440297d7308fdd9b76b70d1b67f12634df6e6296d6c116d5744c6d60d14d3bf3cb978fe6b75ac67b7089bafd50d8687213b31abc7dc1bad422780d29c851d5102b56f932551eaf52a9591fd8c43d81ecc133022653225bd129f8491101725e9ea33e1ded83fb57af35f847e532eb30cd7e726f23910d2671c6364092e834697ec3cef72cc23615a1ba7c5e100156ae0acac3160f0ca9725d38318b7",
          "modulus-size-bits": 2048
        }
      }
    }
  }
  ```
+ To generate an EC private key on an HSM

  Use the [`key generate-asymmetric-pair ec`](cloudhsm_cli-key-generate-asymmetric-pair-ec.md) command to generate an EC key pair. This example generates an EC key pair with the `prime256v1` curve (corresponding to the `NID_X9_62_prime256v1` curve), a public key label of *tls\$1ec\$1pub*, and a private key label of *tls\$1ec\$1private*.

  ```
  aws-cloudhsm > key generate-asymmetric-pair ec \
      --curve prime256v1 \
      --public-label tls_ec_pub \
      --private-label tls_ec_private \
      --private-attributes sign=true
  {
    "error_code": 0,
    "data": {
      "public_key": {
        "key-reference": "0x000000000012000b",
        "key-info": {
          "key-owners": [
            {
              "username": "cu1",
              "key-coverage": "full"
            }
          ],
          "shared-users": [],
          "cluster-coverage": "session"
        },
        "attributes": {
          "key-type": "ec",
          "label": "tls_ec_pub",
          "id": "",
          "check-value": "0xd7c1a7",
          "class": "public-key",
          "encrypt": false,
          "decrypt": false,
          "token": false,
          "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": false,
          "wrap": false,
          "wrap-with-trusted": false,
          "key-length-bytes": 57,
          "ec-point": "0x047096513df542250a6b228fd9cb67fd0c903abc93488467681974d6f371083fce1d79da8ad1e9ede745fb9f38ac8622a1b3ebe9270556000c",
          "curve": "secp224r1"
        }
      },
  "private_key": {
        "key-reference": "0x000000000012000c",
        "key-info": {
          "key-owners": [
            {
              "username": "cu1",
              "key-coverage": "full"
            }
          ],
          "shared-users": [],
          "cluster-coverage": "session"
        },
        "attributes": {
          "key-type": "ec",
          "label": "tls_ec_private",
          "id": "",
          "check-value": "0xd7c1a7",
          "class": "private-key",
          "encrypt": false,
          "decrypt": false,
          "token": false,
          "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": 122,
          "ec-point": "0x047096513df542250a6b228fd9cb67fd0c903abc93488467681974d6f371083fce1d79da8ad1e9ede745fb9f38ac8622a1b3ebe9270556000c",
          "curve": "secp224r1"
        }
      }
    }
  }
  ```

**Export a fake PEM private key file**

Once you have a private key on the HSM, you must export a fake PEM private key file. This file does not contain the actual key data, but it allows the OpenSSL Dynamic Engine to identify the private key on the HSM. You can then you use the private key to create a certificate signing request (CSR) and sign the CSR to create the certificate. 

Use the [`key generate-file`](cloudhsm_cli-key-generate-file.md) command to export the private key in fake PEM format and save it to a file. Replace the following values with your own. 
+ *<private\$1key\$1label>* – Label of the private key you generated in the previous step. 
+ *<web\$1server\$1fake\$1pem.key>* – Name of the file that your fake PEM key will be written to.

```
aws-cloudhsm > key generate-file --encoding reference-pem --path <web_server_fake_pem.key> --filter attr.label=<private_key_label>
{
  "error_code": 0,
  "data": {
    "message": "Successfully generated key file"
  }
}
```

**Exit the CloudHSM CLI**

Run the following command to stop the CloudHSM CLI.

```
aws-cloudhsm > quit
```

You should now have a new file on your system, located at the path specified by *<web\$1server\$1fake\$1pem.key>* in the preceding command. This file is the fake PEM private key file.

#### Generate a self-signed certificate
<a name="ssl-offload-generate-certificate"></a>

Once you have generated a fake PEM private key, you can use this file to generate a certificate signing request (CSR) and certificate.

In a production environment, you typically use a certificate authority (CA) to create a certificate from a CSR. A CA is not necessary for a test environment. If you do use a CA, send the CSR file to them and use signed SSL/TLS certificate that they provide you in your web server for HTTPS. 

As an alternative to using a CA, you can use the AWS CloudHSM OpenSSL Dynamic Engine to create a self-signed certificate. Self-signed certificates are not trusted by browsers and should not be used in production environments. They can be used in test environments. 

**Warning**  
Self-signed certificates should be used in a test environment only. For a production environment, use a more secure method such as a certificate authority to create a certificate. <a name="ssl-offload-generate-certificate-prerequisites"></a>

**Install and configure the OpenSSL Dynamic Engine**

1. Connect to your client instance.

1. [Install the OpenSSL Dynamic Engine for AWS CloudHSM Client SDK 5](openssl5-install.md)<a name="ssl-offload-generate-certificate-steps"></a>

**Generate a certificate**

1. Obtain a copy of your fake PEM file generated in an earlier step.

1. Create a CSR

   Run the following command to use the AWS CloudHSM OpenSSL Dynamic Engine to create a certificate signing request (CSR). Replace *<web\$1server\$1fake\$1pem.key>* with the name of the file that contains your fake PEM private key. Replace *<web\$1server.csr>* with the name of the file that contains your CSR. 

   The `req` command is interactive. Respond to each field. The field information is copied into your SSL/TLS certificate. 

   ```
   $ openssl req -engine cloudhsm -new -key <web_server_fake_pem.key> -out <web_server.csr>
   ```

1. Create a self-signed certificate

   Run the following command to use the AWS CloudHSM OpenSSL Dynamic Engine to sign your CSR with your private key on your HSM. This creates a self-signed certificate. Replace the following values in the command with your own. 
   + *<web\$1server.csr>* – Name of the file that contains the CSR.
   + *<web\$1server\$1fake\$1pem.key>* – Name of the file that contains the fake PEM private key.
   + *<web\$1server.crt>* – Name of the file that will contain your web server certificate.

   ```
   $ openssl x509 -engine cloudhsm -req -days 365 -in <web_server.csr> -signkey <web_server_fake_pem.key> -out <web_server.crt>
   ```

After you complete these steps, go to [Step 3: Configure the web server](#ssl-offload-configure-web-server).

## Step 3: Configure the web server
<a name="ssl-offload-configure-web-server"></a>

Update your web server software's configuration to use the HTTPS certificate and corresponding fake PEM private key that you created in the [previous step](#ssl-offload-import-or-generate-private-key-and-certificate). Remember to backup your existing certificates and keys before you start. This will finish setting up your Linux web server software for SSL/TLS offload with AWS CloudHSM.

Complete the steps from one of the following sections. 

**Topics**
+ [

### Configure NGINX web server
](#ssl-offload-nginx)
+ [

### Configure Apache web server
](#ssl-offload-apache)

### Configure NGINX web server
<a name="ssl-offload-nginx"></a>

Use this section to configure NGINX on supported platforms.<a name="update-web-server-config-nginx"></a>

**To update the web server configuration for NGINX**

1. Connect to your client instance.

1. Run the following command to create the required directories for the web server certificate and the fake PEM private key. 

   ```
   $ sudo mkdir -p /etc/pki/nginx/private
   ```

1. Run the following command to copy your web server certificate to the required location. Replace *<web\$1server.crt>* with the name of your web server certificate.

   ```
   $ sudo cp <web_server.crt> /etc/pki/nginx/server.crt
   ```

1. Run the following command to copy your fake PEM private key to the required location. Replace *<web\$1server\$1fake\$1pem.key>* with the name of the file that contains your fake PEM private key.

   ```
   $ sudo cp <web_server_fake_pem.key> /etc/pki/nginx/private/server.key
   ```

1. Run the following command to change the file ownership so that the user named *nginx* can read them. 

   ```
   $ sudo chown nginx /etc/pki/nginx/server.crt /etc/pki/nginx/private/server.key
   ```

1. Run the following command to back up the `/etc/nginx/nginx.conf` file.

   ```
   $ sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
   ```

1. Update the NGINX configuration.
**Note**  
Each cluster can support a maximum of 1000 NGINX worker processes across all NGINX web servers.

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

   Use a text editor to edit the `/etc/nginx/nginx.conf` file. This requires Linux root permissions. At the top of the file, add the following lines: 

   ```
   ssl_engine cloudhsm;
   env CLOUDHSM_PIN;
   ```

   Then add the following to the TLS section of the file:

   ```
   # Settings for a TLS enabled server.
   server {
       listen       443 ssl http2 default_server;
       listen       [::]:443 ssl http2 default_server;
       server_name  _;
       root         /usr/share/nginx/html;
   
       ssl_certificate "/etc/pki/nginx/server.crt";
       ssl_certificate_key "/etc/pki/nginx/private/server.key";
       # It is *strongly* recommended to generate unique DH parameters
       # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
       #ssl_dhparam "/etc/pki/nginx/dhparams.pem";
       ssl_session_cache shared:SSL:1m;
       ssl_session_timeout  10m;
       ssl_protocols TLSv1.2;
       ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA";
       ssl_prefer_server_ciphers on;
   
       # Load configuration files for the default server block.
       include /etc/nginx/default.d/*.conf;
   
       location / {
       }
   
       error_page 404 /404.html;
       location = /40x.html {
       }
   
       error_page 500 502 503 504 /50x.html;
       location = /50x.html {
       }
   }
   ```

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

   Use a text editor to edit the `/etc/nginx/nginx.conf` file. This requires Linux root permissions. At the top of the file, add the following lines: 

   ```
   ssl_engine cloudhsm;
   env CLOUDHSM_PIN;
   ```

   Then add the following to the TLS section of the file:

   ```
   # Settings for a TLS enabled server.
   server {
       listen       443 ssl http2 default_server;
       listen       [::]:443 ssl http2 default_server;
       server_name  _;
       root         /usr/share/nginx/html;
   
       ssl_certificate "/etc/pki/nginx/server.crt";
       ssl_certificate_key "/etc/pki/nginx/private/server.key";
       # It is *strongly* recommended to generate unique DH parameters
       # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
       #ssl_dhparam "/etc/pki/nginx/dhparams.pem";
       ssl_session_cache shared:SSL:1m;
       ssl_session_timeout  10m;
       ssl_protocols TLSv1.2;
       ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA";
       ssl_prefer_server_ciphers on;
   
       # Load configuration files for the default server block.
       include /etc/nginx/default.d/*.conf;
   
       location / {
       }
   
       error_page 404 /404.html;
       location = /40x.html {
       }
   
       error_page 500 502 503 504 /50x.html;
       location = /50x.html {
       }
   }
   ```

------
#### [ Red Hat 8 ]

   Use a text editor to edit the `/etc/nginx/nginx.conf` file. This requires Linux root permissions. At the top of the file, add the following lines: 

   ```
   ssl_engine cloudhsm;
   env CLOUDHSM_PIN;
   ```

   Then add the following to the TLS section of the file:

   ```
   # Settings for a TLS enabled server.
   server {
       listen       443 ssl http2 default_server;
       listen       [::]:443 ssl http2 default_server;
       server_name  _;
       root         /usr/share/nginx/html;
   
       ssl_certificate "/etc/pki/nginx/server.crt";
       ssl_certificate_key "/etc/pki/nginx/private/server.key";
       # It is *strongly* recommended to generate unique DH parameters
       # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
       #ssl_dhparam "/etc/pki/nginx/dhparams.pem";
       ssl_session_cache shared:SSL:1m;
       ssl_session_timeout  10m;
       ssl_protocols TLSv1.2 TLSv1.3;
       ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA";
       ssl_prefer_server_ciphers on;
   
       # Load configuration files for the default server block.
       include /etc/nginx/default.d/*.conf;
   
       location / {
       }
   
       error_page 404 /404.html;
       location = /40x.html {
       }
   
       error_page 500 502 503 504 /50x.html;
       location = /50x.html {
       }
   }
   ```

------
#### [ Red Hat 9 ]

   Use a text editor to edit the `/etc/nginx/nginx.conf` file. This requires Linux root permissions. At the top of the file, add the following lines: 

   ```
   ssl_engine cloudhsm;
   env CLOUDHSM_PIN;
   ```

   Then add the following to the TLS section of the file:

   ```
   # Settings for a TLS enabled server.
   server {
       listen       443 ssl http2 default_server;
       listen       [::]:443 ssl http2 default_server;
       server_name  _;
       root         /usr/share/nginx/html;
   
       ssl_certificate "/etc/pki/nginx/server.crt";
       ssl_certificate_key "/etc/pki/nginx/private/server.key";
       # It is *strongly* recommended to generate unique DH parameters
       # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
       #ssl_dhparam "/etc/pki/nginx/dhparams.pem";
       ssl_session_cache shared:SSL:1m;
       ssl_session_timeout  10m;
       ssl_protocols TLSv1.2 TLSv1.3;
       ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA";
       ssl_prefer_server_ciphers on;
   
       # Load configuration files for the default server block.
       include /etc/nginx/default.d/*.conf;
   
       location / {
       }
   
       error_page 404 /404.html;
       location = /40x.html {
       }
   
       error_page 500 502 503 504 /50x.html;
       location = /50x.html {
       }
   }
   ```

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

   Use a text editor to edit the `/etc/nginx/nginx.conf` file. This requires Linux root permissions. At the top of the file, add the following lines: 

   ```
   ssl_engine cloudhsm;
   env CLOUDHSM_PIN;
   ```

   Then add the following to the TLS section of the file:

   ```
   # Settings for a TLS enabled server.
   server {
       listen       443 ssl http2 default_server;
       listen       [::]:443 ssl http2 default_server;
       server_name  _;
       root         /usr/share/nginx/html;
   
       ssl_certificate "/etc/pki/nginx/server.crt";
       ssl_certificate_key "/etc/pki/nginx/private/server.key";
       # It is *strongly* recommended to generate unique DH parameters
       # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
       #ssl_dhparam "/etc/pki/nginx/dhparams.pem";
       ssl_session_cache shared:SSL:1m;
       ssl_session_timeout  10m;
       ssl_protocols TLSv1.2 TLSv1.3;
       ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA";
       ssl_prefer_server_ciphers on;
   
       # Load configuration files for the default server block.
       include /etc/nginx/default.d/*.conf;
   
       location / {
       }
   
       error_page 404 /404.html;
       location = /40x.html {
       }
   
       error_page 500 502 503 504 /50x.html;
       location = /50x.html {
       }
   }
   ```

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

   Use a text editor to edit the `/etc/nginx/nginx.conf` file. This requires Linux root permissions. At the top of the file, add the following lines: 

   ```
   ssl_engine cloudhsm;
   env CLOUDHSM_PIN;
   ```

   Then add the following to the TLS section of the file:

   ```
   # Settings for a TLS enabled server.
   server {
       listen       443 ssl http2 default_server;
       listen       [::]:443 ssl http2 default_server;
       server_name  _;
       root         /usr/share/nginx/html;
   
       ssl_certificate "/etc/pki/nginx/server.crt";
       ssl_certificate_key "/etc/pki/nginx/private/server.key";
       # It is *strongly* recommended to generate unique DH parameters
       # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
       #ssl_dhparam "/etc/pki/nginx/dhparams.pem";
       ssl_session_cache shared:SSL:1m;
       ssl_session_timeout  10m;
       ssl_protocols TLSv1.2 TLSv1.3;
       ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA";
       ssl_prefer_server_ciphers on;
   
       # Load configuration files for the default server block.
       include /etc/nginx/default.d/*.conf;
   
       location / {
       }
   
       error_page 404 /404.html;
       location = /40x.html {
       }
   
       error_page 500 502 503 504 /50x.html;
       location = /50x.html {
       }
   }
   ```

------

   Save the file.

1. Back up the `systemd` configuration file, and then set the `EnvironmentFile` path.

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

   1.  Back up the `nginx.service` file. 

      ```
      $ sudo cp /lib/systemd/system/nginx.service /lib/systemd/system/nginx.service.backup
      ```

   1.  Open the `/lib/systemd/system/nginx.service` file in a text editor, and then under the [Service] section, add the following path: 

      ```
      EnvironmentFile=/etc/sysconfig/nginx
      ```

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

   1.  Back up the `nginx.service` file. 

      ```
      $ sudo cp /lib/systemd/system/nginx.service /lib/systemd/system/nginx.service.backup
      ```

   1.  Open the `/lib/systemd/system/nginx.service` file in a text editor. and then under the [Service] section, add the following path: 

      ```
      EnvironmentFile=/etc/sysconfig/nginx
      ```

------
#### [ Red Hat 8 ]

   1.  Back up the `nginx.service` file. 

      ```
      $ sudo cp /lib/systemd/system/nginx.service /lib/systemd/system/nginx.service.backup
      ```

   1.  Open the `/lib/systemd/system/nginx.service` file in a text editor, and then under the [Service] section, add the following path: 

      ```
      EnvironmentFile=/etc/sysconfig/nginx
      ```

------
#### [ Red Hat 9 ]

   1.  Back up the `nginx.service` file. 

      ```
      $ sudo cp /lib/systemd/system/nginx.service /lib/systemd/system/nginx.service.backup
      ```

   1.  Open the `/lib/systemd/system/nginx.service` file in a text editor, and then under the [Service] section, add the following path: 

      ```
      EnvironmentFile=/etc/sysconfig/nginx
      ```

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

   1.  Back up the `nginx.service` file. 

      ```
      $ sudo cp /lib/systemd/system/nginx.service /lib/systemd/system/nginx.service.backup
      ```

   1.  Open the `/lib/systemd/system/nginx.service` file in a text editor, and then under the [Service] section, add the following path: 

      ```
      EnvironmentFile=/etc/sysconfig/nginx
      ```

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

   1.  Back up the `nginx.service` file. 

      ```
      $ sudo cp /lib/systemd/system/nginx.service /lib/systemd/system/nginx.service.backup
      ```

   1.  Open the `/lib/systemd/system/nginx.service` file in a text editor, and then under the [Service] section, add the following path: 

      ```
      EnvironmentFile=/etc/sysconfig/nginx
      ```

------

1.  Check if the `/etc/sysconfig/nginx` file exists, and then do one of the following: 
   + If the file exists, back up the file by running the following command:

     ```
     $ sudo cp /etc/sysconfig/nginx /etc/sysconfig/nginx.backup
     ```
   +  If the file doesn't exist, open a text editor, and then create a file named `nginx` in the `/etc/sysconfig/` folder. 

1. Configure the NGINX environment.
**Note**  
Client SDK 5 introduces the `CLOUDHSM_PIN` environment variable for storing the credentials of the CU.

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

   Open the `/etc/sysconfig/nginx` file in a text editor. This requires Linux root permissions. Add the Cryptography User (CU) credentials:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials. 

    Save the file.

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

   Open the `/etc/sysconfig/nginx` file in a text editor. This requires Linux root permissions. Add the Cryptography User (CU) credentials:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials. 

    Save the file.

------
#### [ Red Hat 8 ]

   Open the `/etc/sysconfig/nginx` file in a text editor. This requires Linux root permissions. Add the Cryptography User (CU) credentials:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials. 

    Save the file.

------
#### [ Red Hat 9 ]

   Open the `/etc/sysconfig/nginx` file in a text editor. This requires Linux root permissions. Add the Cryptography User (CU) credentials:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials. 

    Save the file.

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

   Open the `/etc/sysconfig/nginx` file in a text editor. This requires Linux root permissions. Add the Cryptography User (CU) credentials:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials. 

    Save the file.

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

   Open the `/etc/sysconfig/nginx` file in a text editor. This requires Linux root permissions. Add the Cryptography User (CU) credentials:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials. 

    Save the file.

------

1. Start the NGINX web server.

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

   Stop any running NGINX process

   ```
   $ sudo systemctl stop nginx
   ```

   Reload the `systemd` configuration to pick up the latest changes

   ```
   $ sudo systemctl daemon-reload
   ```

   Start the NGINX process

   ```
   $ sudo systemctl start nginx
   ```

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

   Stop all NGINX processes

   ```
   $ sudo systemctl stop nginx
   ```

   Reload the `systemd` configuration to pick up the latest changes

   ```
   $ sudo systemctl daemon-reload
   ```

   Start NGINX

   ```
   $ sudo systemctl start nginx
   ```

------
#### [ Red Hat 8 ]

   Stop any running NGINX process

   ```
   $ sudo systemctl stop nginx
   ```

   Reload the `systemd` configuration to pick up the latest changes

   ```
   $ sudo systemctl daemon-reload
   ```

   Start the NGINX process

   ```
   $ sudo systemctl start nginx
   ```

------
#### [ Red Hat 9 ]

   Stop any running NGINX process

   ```
   $ sudo systemctl stop nginx
   ```

   Reload the `systemd` configuration to pick up the latest changes

   ```
   $ sudo systemctl daemon-reload
   ```

   Start the NGINX process

   ```
   $ sudo systemctl start nginx
   ```

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

   Stop any running NGINX process

   ```
   $ sudo systemctl stop nginx
   ```

   Reload the `systemd` configuration to pick up the latest changes

   ```
   $ sudo systemctl daemon-reload
   ```

   Start the NGINX process

   ```
   $ sudo systemctl start nginx
   ```

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

   Stop any running NGINX process

   ```
   $ sudo systemctl stop nginx
   ```

   Reload the `systemd` configuration to pick up the latest changes

   ```
   $ sudo systemctl daemon-reload
   ```

   Start the NGINX process

   ```
   $ sudo systemctl start nginx
   ```

------

1. (Optional) Configure your platform to start NGINX at start-up.

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

   ```
   $ sudo systemctl enable nginx
   ```

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

   ```
   $ sudo systemctl enable nginx
   ```

------
#### [ Red Hat 8 ]

   ```
   $ sudo systemctl enable nginx
   ```

------
#### [ Red Hat 9 ]

   ```
   $ sudo systemctl enable nginx
   ```

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

   ```
   $ sudo systemctl enable nginx
   ```

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

   ```
   $ sudo systemctl enable nginx
   ```

------

After you update your web server configuration, go to [Step 4: Enable HTTPS traffic and verify the certificate](#ssl-offload-enable-traffic-and-verify-certificate).

### Configure Apache web server
<a name="ssl-offload-apache"></a>

 Use this section to configure Apache on supported platforms. <a name="update-web-server-config-apache"></a>

**To update the web server configuration for Apache**

1. Connect to your Amazon EC2 client instance.

1. Define default locations for certificates and private keys for your platform.

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

   In the `/etc/httpd/conf.d/ssl.conf` file, ensure these values exist:

   ```
   SSLCertificateFile      /etc/pki/tls/certs/localhost.crt
   SSLCertificateKeyFile   /etc/pki/tls/private/localhost.key
   ```

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

   In the `/etc/httpd/conf.d/ssl.conf` file. ensure these values exist:

   ```
   SSLCertificateFile      /etc/pki/tls/certs/localhost.crt
   SSLCertificateKeyFile   /etc/pki/tls/private/localhost.key
   ```

------
#### [ Red Hat 8 ]

   In the `/etc/httpd/conf.d/ssl.conf` file, ensure these values exist:

   ```
   SSLCertificateFile      /etc/pki/tls/certs/localhost.crt
   SSLCertificateKeyFile   /etc/pki/tls/private/localhost.key
   ```

------
#### [ Red Hat 9 ]

   In the `/etc/httpd/conf.d/ssl.conf` file, ensure these values exist:

   ```
   SSLCertificateFile      /etc/pki/tls/certs/localhost.crt
   SSLCertificateKeyFile   /etc/pki/tls/private/localhost.key
   ```

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

   In the `/etc/apache2/sites-available/default-ssl.conf` file, ensure these values exist:

   ```
   SSLCertificateFile      /etc/ssl/certs/localhost.crt
   SSLCertificateKeyFile   /etc/ssl/private/localhost.key
   ```

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

   In the `/etc/apache2/sites-available/default-ssl.conf` file, ensure these values exist:

   ```
   SSLCertificateFile      /etc/ssl/certs/localhost.crt
   SSLCertificateKeyFile   /etc/ssl/private/localhost.key
   ```

------

1. Copy your web server certificate to the required location for your platform.

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

   ```
   $ sudo cp <web_server.crt> /etc/pki/tls/certs/localhost.crt
   ```

   Replace *<web\$1server.crt>* with the name of your web server certificate. 

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

   ```
   $ sudo cp <web_server.crt> /etc/pki/tls/certs/localhost.crt
   ```

   Replace *<web\$1server.crt>* with the name of your web server certificate. 

------
#### [ Red Hat 8 ]

   ```
   $ sudo cp <web_server.crt> /etc/pki/tls/certs/localhost.crt
   ```

   Replace *<web\$1server.crt>* with the name of your web server certificate. 

------
#### [ Red Hat 9 ]

   ```
   $ sudo cp <web_server.crt> /etc/pki/tls/certs/localhost.crt
   ```

   Replace *<web\$1server.crt>* with the name of your web server certificate. 

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

   ```
   $ sudo cp <web_server.crt> /etc/ssl/certs/localhost.crt
   ```

   Replace *<web\$1server.crt>* with the name of your web server certificate. 

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

   ```
   $ sudo cp <web_server.crt> /etc/ssl/certs/localhost.crt
   ```

   Replace *<web\$1server.crt>* with the name of your web server certificate. 

------

1. Copy your fake PEM private key to the required location for your platform.

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

   ```
   $ sudo cp <web_server_fake_pem.key> /etc/pki/tls/private/localhost.key
   ```

   Replace *<web\$1server\$1fake\$1pem.key>* with the name of the file that contains your fake PEM private key.

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

   ```
   $ sudo cp <web_server_fake_pem.key> /etc/pki/tls/private/localhost.key
   ```

   Replace *<web\$1server\$1fake\$1pem.key>* with the name of the file that contains your fake PEM private key.

------
#### [ Red Hat 8 ]

   ```
   $ sudo cp <web_server_fake_pem.key> /etc/pki/tls/private/localhost.key
   ```

   Replace *<web\$1server\$1fake\$1pem.key>* with the name of the file that contains your fake PEM private key.

------
#### [ Red Hat 9 ]

   ```
   $ sudo cp <web_server_fake_pem.key> /etc/pki/tls/private/localhost.key
   ```

   Replace *<web\$1server\$1fake\$1pem.key>* with the name of the file that contains your fake PEM private key.

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

   ```
   $ sudo cp <web_server_fake_pem.key> /etc/ssl/private/localhost.key
   ```

   Replace *<web\$1server\$1fake\$1pem.key>* with the name of the file that contains your fake PEM private key.

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

   ```
   $ sudo cp <web_server_fake_pem.key> /etc/ssl/private/localhost.key
   ```

   Replace *<web\$1server\$1fake\$1pem.key>* with the name of the file that contains your fake PEM private key.

------

1. Change ownership of these files if required by your platform.

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

   ```
   $ sudo chown apache /etc/pki/tls/certs/localhost.crt /etc/pki/tls/private/localhost.key
   ```

   Provides read permission to the user named *apache*.

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

   ```
   $ sudo chown apache /etc/pki/tls/certs/localhost.crt /etc/pki/tls/private/localhost.key
   ```

   Provides read permission to the user named *apache*.

------
#### [ Red Hat 8 ]

   ```
   $ sudo chown apache /etc/pki/tls/certs/localhost.crt /etc/pki/tls/private/localhost.key
   ```

   Provides read permission to the user named *apache*.

------
#### [ Red Hat 9 ]

   ```
   $ sudo chown apache /etc/pki/tls/certs/localhost.crt /etc/pki/tls/private/localhost.key
   ```

   Provides read permission to the user named *apache*.

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

   No action required.

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

   No action required.

------

1. Configure Apache directives for your platform.

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

   Locate the SSL file for this platform:

   ```
   /etc/httpd/conf.d/ssl.conf
   ```

   This file contains Apache directives which define how your server should run. Directives appear on the left, followed by a value. Use a text editor to edit this file. This requires Linux root permissions.

   Update or enter the following directives with these values:

   ```
   SSLCryptoDevice cloudhsm
   SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA
   ```

   Save the file.

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

   Locate the SSL file for this platform:

   ```
   /etc/httpd/conf.d/ssl.conf
   ```

   This file contains Apache directives which define how your server should run. Directives appear on the left, followed by a value. Use a text editor to edit this file. This requires Linux root permissions.

   Update or enter the following directives with these values:

   ```
   SSLCryptoDevice cloudhsm
   SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA
   ```

   Save the file.

------
#### [ Red Hat 8 ]

   Locate the SSL file for this platform:

   ```
   /etc/httpd/conf.d/ssl.conf
   ```

   This file contains Apache directives which define how your server should run. Directives appear on the left, followed by a value. Use a text editor to edit this file. This requires Linux root permissions.

   Update or enter the following directives with these values:

   ```
   SSLCryptoDevice cloudhsm
   SSLProtocol TLSv1.2 TLSv1.3
   SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA
   SSLProxyCipherSuite HIGH:!aNULL
   ```

   Save the file.

------
#### [ Red Hat 9 ]

   Locate the SSL file for this platform:

   ```
   /etc/httpd/conf.d/ssl.conf
   ```

   This file contains Apache directives which define how your server should run. Directives appear on the left, followed by a value. Use a text editor to edit this file. This requires Linux root permissions.

   Update or enter the following directives with these values:

   ```
   SSLCryptoDevice cloudhsm
   SSLProtocol TLSv1.2 TLSv1.3
   SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA
   SSLProxyCipherSuite HIGH:!aNULL
   ```

   Save the file.

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

   Locate the SSL file for this platform:

   ```
   /etc/apache2/mods-available/ssl.conf
   ```

   This file contains Apache directives which define how your server should run. Directives appear on the left, followed by a value. Use a text editor to edit this file. This requires Linux root permissions.

   Update or enter the following directives with these values:

   ```
   SSLCryptoDevice cloudhsm
   SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA
   SSLProtocol TLSv1.2 TLSv1.3
   ```

   Save the file.

   Enable the SSL module and default SSL site configuration:

   ```
   $ sudo a2enmod ssl
   $ sudo a2ensite default-ssl
   ```

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

   Locate the SSL file for this platform:

   ```
   /etc/apache2/mods-available/ssl.conf
   ```

   This file contains Apache directives which define how your server should run. Directives appear on the left, followed by a value. Use a text editor to edit this file. This requires Linux root permissions.

   Update or enter the following directives with these values:

   ```
   SSLCryptoDevice cloudhsm
   SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA
   SSLProtocol TLSv1.2 TLSv1.3
   ```

   Save the file.

   Enable the SSL module and default SSL site configuration:

   ```
   $ sudo a2enmod ssl
   $ sudo a2ensite default-ssl
   ```

------

1. Configure an environment-values file for your platform.

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

    Open the httpd service file: 

   ```
   /lib/systemd/system/httpd.service
   ```

    Under the `[Service]` section, add the following: 

   ```
   EnvironmentFile=/etc/sysconfig/httpd
   ```

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

    Open the httpd service file: 

   ```
   /lib/systemd/system/httpd.service
   ```

    Under the `[Service]` section, add the following: 

   ```
   EnvironmentFile=/etc/sysconfig/httpd
   ```

------
#### [ Red Hat 8 ]

    Open the httpd service file: 

   ```
   /lib/systemd/system/httpd.service
   ```

    Under the `[Service]` section, add the following: 

   ```
   EnvironmentFile=/etc/sysconfig/httpd
   ```

------
#### [ Red Hat 9 ]

    Open the httpd service file: 

   ```
   /lib/systemd/system/httpd.service
   ```

    Under the `[Service]` section, add the following: 

   ```
   EnvironmentFile=/etc/sysconfig/httpd
   ```

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

   No action required. Environment values go in `/etc/sysconfig/httpd`

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

   No action required. Environment values go in `/etc/sysconfig/httpd`

------

1. In the file that stores environment variables for your platform, set an environment variable that contains the credentials of the cryptographic user (CU):

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

   Use a text editor to edit the `/etc/sysconfig/httpd`.

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials.

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

   Use a text editor to edit the `/etc/sysconfig/httpd`.

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials.

------
#### [ Red Hat 8 ]

   Use a text editor to edit the `/etc/sysconfig/httpd`.

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials.

**Note**  
Client SDK 5 introduces the `CLOUDHSM_PIN` environment variable for storing the credentials of the CU.

------
#### [ Red Hat 9 ]

   Use a text editor to edit the `/etc/sysconfig/httpd`.

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials.

**Note**  
Client SDK 5 introduces the `CLOUDHSM_PIN` environment variable for storing the credentials of the CU.

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

   Use a text editor to edit the `/etc/apache2/envvars`.

   ```
   export CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials.

**Note**  
Client SDK 5 introduces the `CLOUDHSM_PIN` environment variable for storing the credentials of the CU. In Client SDK 3 you stored the CU credentials in the `n3fips_password` environment variable. Client SDK 5 supports both environment variables, but we recommend using `CLOUDHSM_PIN`.

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

   Use a text editor to edit the `/etc/apache2/envvars`.

   ```
   export CLOUDHSM_PIN=<CU user name>:<password>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials.

**Note**  
Client SDK 5 introduces the `CLOUDHSM_PIN` environment variable for storing the credentials of the CU. In Client SDK 3 you stored the CU credentials in the `n3fips_password` environment variable. Client SDK 5 supports both environment variables, but we recommend using `CLOUDHSM_PIN`.

------

1. Start the Apache web server.

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

   ```
   $ sudo systemctl daemon-reload
   $ sudo service httpd start
   ```

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

   ```
   $ sudo systemctl daemon-reload
   $ sudo service httpd start
   ```

------
#### [ Red Hat 8 ]

   ```
   $ sudo systemctl daemon-reload
   $ sudo service httpd start
   ```

------
#### [ Red Hat 9 ]

   ```
   $ sudo systemctl daemon-reload
   $ sudo service httpd start
   ```

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

   ```
   $ sudo service apache2 start
   ```

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

   ```
   $ sudo service apache2 start
   ```

------

1. (Optional) Configure your platform to start Apache at start-up.

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

   ```
   $ sudo chkconfig httpd on
   ```

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

   ```
   $ sudo chkconfig httpd on
   ```

------
#### [ Red Hat 8 ]

   ```
   $ systemctl enable httpd
   ```

------
#### [ Red Hat 9 ]

   ```
   $ systemctl enable httpd
   ```

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

   ```
   $ sudo systemctl enable apache2
   ```

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

   ```
   $ sudo systemctl enable apache2
   ```

------

After you update your web server configuration, go to [Step 4: Enable HTTPS traffic and verify the certificate](#ssl-offload-enable-traffic-and-verify-certificate).

## Step 4: Enable HTTPS traffic and verify the certificate
<a name="ssl-offload-enable-traffic-and-verify-certificate"></a>

After you configure your web server for SSL/TLS offload with AWS CloudHSM, add your web server instance to a security group that allows inbound HTTPS traffic. This allows clients, such as web browsers, to establish an HTTPS connection with your web server. Then make an HTTPS connection to your web server and verify that it's using the certificate that you configured for SSL/TLS offload with AWS CloudHSM.

**Topics**
+ [

### Enable inbound HTTPS connections
](#ssl-offload-add-security-group-linux)
+ [

### Verify that HTTPS uses the certificate that you configured
](#ssl-offload-verify-https-connection-linux-enable)

### Enable inbound HTTPS connections
<a name="ssl-offload-add-security-group-linux"></a>

To connect to your web server from a client (such as a web browser), create a security group that allows inbound HTTPS connections. Specifically, it should allow inbound TCP connections on port 443. Assign this security group to your web server. 

**To create a security group for HTTPS and assign it to your web server**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. Choose **Security groups** in the navigation pane.

1. Choose **Create security group**.

1. For **Create Security Group**, do the following:

   1. For **Security group name**, type a name for the security group that you are creating.

   1. (Optional) Type a description of the security group that you are creating.

   1. For **VPC**, choose the VPC that contains your web server Amazon EC2 instance.

   1. Select **Add Rule**.

   1. For **Type**, select **HTTPS** from the drop-down window.

   1. For **Source**, enter a source location.

   1. Choose **Create security group**.

1. In the navigation pane, choose **Instances**.

1. Select the check box next to your web server instance.

1. Select the **Actions** drop-down menu at the top of the page. Select **Security** and then **Change Security Groups**.

1. For **Associated security groups**, select the search box and choose the security group that you created for HTTPS. Then choose **Add Security Groups**.

1. Select **Save**. 

### Verify that HTTPS uses the certificate that you configured
<a name="ssl-offload-verify-https-connection-linux-enable"></a>

After you add the web server to a security group, you can verify that SSL/TLS offload is using your self-signed certificate. You can do this with a web browser or with a tool such as [OpenSSL s\$1client](https://www.openssl.org/docs/manmaster/man1/s_client.html).

**To verify SSL/TLS offload with a web browser**

1. Use a web browser to connect to your web server using the public DNS name or IP address of the server. Ensure that the URL in the address bar begins with https://. For example, **https://ec2-52-14-212-67.us-east-2.compute.amazonaws.com/**.
**Tip**  
You can use a DNS service such as Amazon Route 53 to route your website's domain name (for example, https://www.example.com/) to your web server. For more information, see [Routing Traffic to an Amazon EC2 Instance](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html) in the *Amazon Route 53 Developer Guide* or in the documentation for your DNS service.

1. Use your web browser to view the web server certificate. For more information, see the following:
   + For Mozilla Firefox, see [View a Certificate](https://support.mozilla.org/en-US/kb/secure-website-certificate#w_view-a-certificate) on the Mozilla Support website.
   + For Google Chrome, see [Understand Security Issues](https://developers.google.com/web/tools/chrome-devtools/security) on the Google Tools for Web Developers website.

   Other web browsers might have similar features that you can use to view the web server certificate.

1. Ensure that the SSL/TLS certificate is the one that you configured your web server to use.

**To verify SSL/TLS offload with OpenSSL s\$1client**

1. Run the following OpenSSL command to connect to your web server using HTTPS. Replace *<server name>* with the public DNS name or IP address of your web server. 

   ```
   openssl s_client -connect <server name>:443
   ```
**Tip**  
You can use a DNS service such as Amazon Route 53 to route your website's domain name (for example, https://www.example.com/) to your web server. For more information, see [Routing Traffic to an Amazon EC2 Instance](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html) in the *Amazon Route 53 Developer Guide* or in the documentation for your DNS service.

1. Ensure that the SSL/TLS certificate is the one that you configured your web server to use.

You now have a website that is secured with HTTPS. The private key for the web server is stored in an HSM in your AWS CloudHSM cluster. 

To add a load balancer, see [Add a load balancer with Elastic Load Balancing for AWS CloudHSM(optional)](third-offload-add-lb.md).

# AWS CloudHSM SSL/TLS offload on Linux using NGINX or HAProxy with OpenSSL Provider
<a name="third-offload-linux-openssl-provider"></a>

This topic provides step-by-step instructions for setting up SSL/TLS server identity offload with AWS CloudHSM on a Linux web server using NGINX or HAProxy with the OpenSSL Provider.

**Topics**
+ [

## Overview
](#ssl-offload-linux-openssl-provider-overview)
+ [

## Step 1: Set up the prerequisites
](#ssl-offload-provider-prerequisites)
+ [

## Step 2: Generate or import a private key and get a certificate
](#ssl-offload-provider-generate-key-and-certificate)
+ [

## Step 3: Configure the web server
](#ssl-offload-provider-configure-web-server)
+ [

## Step 4: Enable HTTPS traffic and verify the certificate
](#ssl-offload-enable-traffic-and-verify-certificate-provider)

## Overview
<a name="ssl-offload-linux-openssl-provider-overview"></a>

On Linux, the [NGINX](https://nginx.org/en/) and [HAProxy](https://www.haproxy.org/) web server software integrate with [OpenSSL](https://www.openssl.org/) to support HTTPS. The [AWS CloudHSM OpenSSL Provider](openssl-provider-library.md) provides an interface that enables the web server software to use the HSMs in your cluster for cryptographic offloading and key storage. The OpenSSL Provider is the bridge that connects the web server to your AWS CloudHSM cluster.

To complete this tutorial, you will configure NGINX or HAProxy to use the AWS CloudHSM OpenSSL Provider. The tutorial shows you how to do the following:
+ Install the web server software on an Amazon EC2 instance.
+ Configure the web server software to support HTTPS with a private key stored in your AWS CloudHSM cluster.
+ (Optional) Use Amazon EC2 to create a second web server instance and Elastic Load Balancing to create a load balancer. Using a load balancer can increase performance by distributing the load across multiple servers. It can also provide redundancy and higher availability if one or more servers fail.

When you're ready to get started, go to [Step 1: Set up the prerequisites](#ssl-offload-provider-prerequisites).

## Step 1: Set up the prerequisites
<a name="ssl-offload-provider-prerequisites"></a>

Different platforms require different prerequisites. Use the prerequisites section below that matches your platform.

### Prerequisites for AWS CloudHSM OpenSSL Provider
<a name="provider-new-versions"></a>

To set up web server SSL/TLS server identity offload with AWS CloudHSM OpenSSL Provider for Client SDK 5, you need the following:
+ An active AWS CloudHSM cluster with at least two hardware security modules (HSM)
**Note**  
You can use a single HSM cluster, but you must first disable client key durability. For more information, see [Manage Client Key Durability Settings](working-client-sync.md#client-sync-sdk8) and [Client SDK 5 Configure Tool](configure-sdk-5.md).
+ An Amazon EC2 instance running a Linux operating system with the following software installed:
  + A web server (either NGINX or HAProxy)
  + The AWS CloudHSM OpenSSL Provider for Client SDK 5
+ A [crypto user](understanding-users.md#crypto-user-chsm-cli) (CU) to own and manage the web server's private key on the HSM.

**To set up a Linux web server instance and create a CU on the HSM**
**Note**  
Many of the commands in this procedure require elevated privileges. You may need to run commands with `sudo` or as the root user depending on your system configuration.

1. Install and configure the AWS CloudHSM OpenSSL Provider for Client SDK 5. For more information about installing the OpenSSL Provider, see [AWS CloudHSM OpenSSL Provider for Client SDK 5](openssl-provider-install.md).

1. On an EC2 Linux instance that has access to your cluster, install either NGINX or HAProxy web server:

------
#### [ Amazon Linux 2023 ]
   + NGINX

     ```
     $ yum install nginx
     ```
   + HAProxy

     ```
     $ yum install haproxy
     ```

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

     ```
     $ yum install nginx
     ```
   + HAProxy

     ```
     $ yum install haproxy
     ```

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

     ```
     $ yum install nginx
     ```
   + HAProxy

     ```
     $ yum install haproxy
     ```

------
#### [ Ubuntu 24.04 ]
   + NGINX

     ```
     $ apt install nginx
     ```
   + HAProxy

     ```
     $ apt install haproxy
     ```

------

1. Use CloudHSM CLI to create a [crypto user](understanding-users.md#crypto-user-chsm-cli). For more information about managing HSM users, see [Managing HSM users with CloudHSM CLI](manage-hsm-users-chsm-cli.md).
**Tip**  
Keep track of the CU user name and password. You will need them later when you generate or import the HTTPS private key and certificate for your web server.

After you complete these steps, go to [Step 2: Generate or import a private key and get a certificate](#ssl-offload-provider-generate-key-and-certificate).

#### Notes
<a name="note-ssl5-provider-pre"></a>
+ To use Security-Enhanced Linux (SELinux) and web servers, you must allow outbound TCP connections on port 2223, which is the port Client SDK 5 uses to communicate with the HSM.
+ To create and activate a cluster and give an EC2 instance access to the cluster, complete the steps in [Getting Started with AWS CloudHSM](getting-started.md). The getting started offers step-by-step instruction for creating an active cluster with one HSM and an Amazon EC2 client instance. You can use this client instance as your web server. 
+ To avoid disabling client key durability, add more than one HSM to your cluster. For more information, see [Adding an HSM to an AWS CloudHSM cluster](add-hsm.md).
+ To connect to your client instance, you can use SSH or PuTTY. For more information, see [Connecting to Your Linux Instance Using SSH](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html) or [Connecting to Your Linux Instance from Windows Using PuTTY](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html) in the Amazon EC2 documentation. 

## Step 2: Generate or import a private key and get a certificate
<a name="ssl-offload-provider-generate-key-and-certificate"></a>

To enable HTTPS, your web server application (NGINX or HAProxy) needs a private key and a corresponding SSL/TLS certificate. To use web server SSL/TLS server identity offload with AWS CloudHSM, you must store the private key in an HSM in your AWS CloudHSM cluster. You will first generate a private key and use the key to create a certificate signing request (CSR). You then export a *fake PEM private key* from the HSM, which is a private key file in PEM format which contains a reference to the private key stored on the HSM (it's not the actual private key). Your web server uses the fake PEM private key file to identify the private key on the HSM during SSL/TLS server identity offload.

### Generate a private key
<a name="ssl-offload-provider-generate-private-key"></a>

This section shows you how to generate a keypair using the [CloudHSM CLI](cloudhsm_cli.md). Once you have a key pair generated inside the HSM, you can export it as a fake PEM file and generate the corresponding certificate. <a name="ssl-offload-provider-generate-private-key-prerequisites"></a>

**Install and configure the CloudHSM CLI**

1. [Install and Configure](cloudhsm_cli-getting-started.md) the CloudHSM CLI.

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

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

1. Run the following command to log in to the HSM. Replace *<user name>* with the user name of your crypto-user

   ```
   aws-cloudhsm>login --username <user name> --role crypto-user
   ```

**Generate a Private Key**

Depending on your use case, you can either generate an RSA or an EC key pair. Do one of the following:
+ To generate an RSA private key on an HSM

  Use the [`key generate-asymmetric-pair rsa`](cloudhsm_cli-key-generate-asymmetric-pair-rsa.md) command to generate an RSA key pair. This example generates an RSA key pair with a modulus of 2048, a public exponent of 65537, public key label of *tls\$1rsa\$1pub*, and private key label of *tls\$1rsa\$1private*.

  ```
  aws-cloudhsm > key generate-asymmetric-pair rsa \
  --public-exponent 65537 \
  --modulus-size-bits 2048 \
  --public-label tls_rsa_pub \
  --private-label tls_rsa_private \
  --private-attributes sign=true
  {
    "error_code": 0,
    "data": {
      "public_key": {
        "key-reference": "0x0000000000280cc8",
        "key-info": {
          "key-owners": [
            {
              "username": "cu1",
              "key-coverage": "full"
            }
          ],
          "shared-users": [],
          "cluster-coverage": "full"
        },
        "attributes": {
          "key-type": "rsa",
          "label": "tls_rsa_pub",
          "id": "",
          "check-value": "0x01fe6e",
          "class": "public-key",
          "encrypt": true,
          "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": false,
          "wrap": false,
          "wrap-with-trusted": false,
          "key-length-bytes": 512,
          "public-exponent": "0x010001",
          "modulus": "0xb1d27e857a876f4e9fd5de748a763c539b359f937eb4b4260e30d1435485a732c878cdad9c72538e2215351b1d41358c9bf80b599c73a80fdb457aa7b20cd61e486c326e2cfd5e124a7f6a996437437812b542e3caf85928aa866f0298580f7967ee6aa01440297d7308fdd9b76b70d1b67f12634df6e6296d6c116d5744c6d60d14d3bf3cb978fe6b75ac67b7089bafd50d8687213b31abc7dc1bad422780d29c851d5102b56f932551eaf52a9591fd8c43d81ecc133022653225bd129f8491101725e9ea33e1ded83fb57af35f847e532eb30cd7e726f23910d2671c6364092e834697ec3cef72cc23615a1ba7c5e100156ae0acac3160f0ca9725d38318b7",
          "modulus-size-bits": 2048
        }
      },
      "private_key": {
        "key-reference": "0x0000000000280cc7",
        "key-info": {
          "key-owners": [
            {
              "username": "cu1",
              "key-coverage": "full"
            }
          ],
          "shared-users": [],
          "cluster-coverage": "full"
        },
        "attributes": {
          "key-type": "rsa",
          "label": "tls_rsa_private",
          "id": "",
          "check-value": "0x01fe6e",
          "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": false,
          "verify": false,
          "wrap": false,
          "wrap-with-trusted": false,
          "key-length-bytes": 1217,
          "public-exponent": "0x010001",
          "modulus": "0xb1d27e857a876f4e9fd5de748a763c539b359f937eb4b4260e30d1435485a732c878cdad9c72538e2215351b1d41358c9bf80b599c73a80fdb457aa7b20cd61e486c326e2cfd5e124a7f6a996437437812b542e3caf85928aa866f0298580f7967ee6aa01440297d7308fdd9b76b70d1b67f12634df6e6296d6c116d5744c6d60d14d3bf3cb978fe6b75ac67b7089bafd50d8687213b31abc7dc1bad422780d29c851d5102b56f932551eaf52a9591fd8c43d81ecc133022653225bd129f8491101725e9ea33e1ded83fb57af35f847e532eb30cd7e726f23910d2671c6364092e834697ec3cef72cc23615a1ba7c5e100156ae0acac3160f0ca9725d38318b7",
          "modulus-size-bits": 2048
        }
      }
    }
  }
  ```
+ To generate an EC private key on an HSM

  Use the [`key generate-asymmetric-pair ec`](cloudhsm_cli-key-generate-asymmetric-pair-ec.md) command to generate an EC key pair. This example generates an EC key pair with the `prime256v1` curve (corresponding to the `NID_X9_62_prime256v1` curve), a public key label of *tls\$1ec\$1pub*, and a private key label of *tls\$1ec\$1private*.

  ```
  aws-cloudhsm > key generate-asymmetric-pair ec \
      --curve prime256v1 \
      --public-label tls_ec_pub \
      --private-label tls_ec_private \
      --private-attributes sign=true
  {
    "error_code": 0,
    "data": {
      "public_key": {
        "key-reference": "0x000000000012000b",
        "key-info": {
          "key-owners": [
            {
              "username": "cu1",
              "key-coverage": "full"
            }
          ],
          "shared-users": [],
          "cluster-coverage": "session"
        },
        "attributes": {
          "key-type": "ec",
          "label": "tls_ec_pub",
          "id": "",
          "check-value": "0xd7c1a7",
          "class": "public-key",
          "encrypt": false,
          "decrypt": false,
          "token": false,
          "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": false,
          "wrap": false,
          "wrap-with-trusted": false,
          "key-length-bytes": 57,
          "ec-point": "0x047096513df542250a6b228fd9cb67fd0c903abc93488467681974d6f371083fce1d79da8ad1e9ede745fb9f38ac8622a1b3ebe9270556000c",
          "curve": "secp224r1"
        }
      },
  "private_key": {
        "key-reference": "0x000000000012000c",
        "key-info": {
          "key-owners": [
            {
              "username": "cu1",
              "key-coverage": "full"
            }
          ],
          "shared-users": [],
          "cluster-coverage": "session"
        },
        "attributes": {
          "key-type": "ec",
          "label": "tls_ec_private",
          "id": "",
          "check-value": "0xd7c1a7",
          "class": "private-key",
          "encrypt": false,
          "decrypt": false,
          "token": false,
          "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": 122,
          "ec-point": "0x047096513df542250a6b228fd9cb67fd0c903abc93488467681974d6f371083fce1d79da8ad1e9ede745fb9f38ac8622a1b3ebe9270556000c",
          "curve": "secp224r1"
        }
      }
    }
  }
  ```

**Export a fake PEM private key file**

Once you have a private key on the HSM, you must export a fake PEM private key file. This file does not contain the actual key data, but it allows the OpenSSL Dynamic Engine to identify the private key on the HSM. You can then you use the private key to create a certificate signing request (CSR) and sign the CSR to create the certificate. 

Use the [`key generate-file`](cloudhsm_cli-key-generate-file.md) command to export the private key in fake PEM format and save it to a file. Replace the following values with your own. 
+ *<private\$1key\$1label>* – Label of the private key you generated in the previous step. 
+ *<web\$1server\$1fake\$1pem.key>* – Name of the file that your fake PEM key will be written to.

```
aws-cloudhsm > key generate-file --encoding reference-pem --path <web_server_fake_pem.key> --filter attr.label=<private_key_label>
{
  "error_code": 0,
  "data": {
    "message": "Successfully generated key file"
  }
}
```

**Exit the CloudHSM CLI**

Run the following command to stop the CloudHSM CLI.

```
aws-cloudhsm > quit
```

You should now have a new file on your system, located at the path specified by *<web\$1server\$1fake\$1pem.key>* in the preceding command. This file is the fake PEM private key file.

### Generate a self-signed certificate
<a name="ssl-offload-provider-generate-certificate"></a>

Once you have generated a fake PEM private key, you can use this file to generate a certificate signing request (CSR) and certificate.

In a production environment, you typically use a certificate authority (CA) to create a certificate from a CSR. A CA is not necessary for a test environment. If you do use a CA, send the CSR file to them and use signed SSL/TLS certificate that they provide you in your web server for HTTPS. 

As an alternative to using a CA, you can use the AWS CloudHSM OpenSSL Dynamic Engine to create a self-signed certificate. Self-signed certificates are not trusted by browsers and should not be used in production environments. They can be used in test environments. 

**Warning**  
Self-signed certificates should be used in a test environment only. For a production environment, use a more secure method such as a certificate authority to create a certificate. <a name="ssl-offload-provider-generate-certificate-prerequisites"></a>

**Install and configure the OpenSSL Dynamic Engine**

1. Connect to your client instance.

1. [Install the OpenSSL Dynamic Engine for AWS CloudHSM Client SDK 5](openssl5-install.md)<a name="ssl-offload-provider-generate-certificate-steps"></a>

**Generate a certificate**

1. Obtain a copy of your fake PEM file generated in an earlier step.

1. Create a CSR

   Run the following command to use the AWS CloudHSM OpenSSL Dynamic Engine to create a certificate signing request (CSR). Replace *<web\$1server\$1fake\$1pem.key>* with the name of the file that contains your fake PEM private key. Replace *<web\$1server.csr>* with the name of the file that contains your CSR. 

   The `req` command is interactive. Respond to each field. The field information is copied into your SSL/TLS certificate. 
**Note**  
CSR creation is not currently supported with the OpenSSL Provider. You must use the OpenSSL Engine for this step, but TLS cipher operations will work with the Provider.

   ```
   $ openssl req -engine cloudhsm -new -key <web_server_fake_pem.key> -out <web_server.csr>
   ```

1. Create a self-signed certificate

   Run the following command to use the AWS CloudHSM OpenSSL Dynamic Engine to sign your CSR with your private key on your HSM. This creates a self-signed certificate. Replace the following values in the command with your own. 
   + *<web\$1server.csr>* – Name of the file that contains the CSR.
   + *<web\$1server\$1fake\$1pem.key>* – Name of the file that contains the fake PEM private key.
   + *<web\$1server.crt>* – Name of the file that will contain your web server certificate.

   ```
   $ openssl x509 -engine cloudhsm -req -days 365 -in <web_server.csr> -signkey <web_server_fake_pem.key> -out <web_server.crt>
   ```

After you have a private key and certificate, go to [Step 3: Configure the web server](#ssl-offload-provider-configure-web-server).

## Step 3: Configure the web server
<a name="ssl-offload-provider-configure-web-server"></a>

Update your web server software's configuration to use the HTTPS certificate and corresponding fake PEM private key that you created in the [previous step](#ssl-offload-provider-generate-key-and-certificate). Remember to backup your existing certificates and keys before you start. This will finish setting up your Linux web server software for SSL/TLS server identity offload with AWS CloudHSM.

Complete the steps from one of the following sections. 

**Topics**
+ [

### Configure NGINX web server
](#ssl-offload-provider-configure-nginx)
+ [

### Configure HAProxy web server
](#ssl-offload-provider-configure-haproxy)

### Configure NGINX web server
<a name="ssl-offload-provider-configure-nginx"></a>

Use this section to configure NGINX with the OpenSSL Provider.<a name="configure-nginx-provider"></a>

**To configure NGINX for OpenSSL Provider**

1. Connect to your client instance.

1. Run the following command to create the required directories for the web server certificate and the fake PEM private key.

   ```
   $ mkdir -p /etc/pki/nginx/private
   ```

1. Run the following command to copy your web server certificate to the required location. Replace *<web\$1server.crt>* with the name of your web server certificate.

   ```
   $ cp <web_server.crt> /etc/pki/nginx/server.crt
   ```

1. Run the following command to copy your fake PEM private key to the required location. Replace *<web\$1server\$1fake\$1pem.key>* with the name of the file that contains your fake PEM private key.

   ```
   $ cp <web_server_fake_pem.key> /etc/pki/nginx/private/server.key
   ```

1. Run the following command to change the file ownership so that the user named *nginx* can read them.

   ```
   $ chown nginx /etc/pki/nginx/server.crt /etc/pki/nginx/private/server.key
   ```

1. Configure OpenSSL to use the AWS CloudHSM provider. For more information about configuring the OpenSSL Provider, see [AWS CloudHSM OpenSSL Provider for Client SDK 5](openssl-provider-install.md).

   1. Locate your OpenSSL configuration file:

      ```
      $ openssl version -d
      ```

      You should see output similar to:

      ```
      OPENSSLDIR: "/etc/pki/tls"
      ```

      The configuration file is `openssl.cnf` in this directory.

   1. 
**Note**  
Do not modify your system's default openssl.cnf file directly. This prevents system-wide OpenSSL operations (SSH, TLS connections, and other services) from unintentionally routing through the CloudHSM provider.  
Using a separate configuration file allows you to scope CloudHSM Provider usage to only specific applications that require HSM-backed cryptographic operations.

      Create a new OpenSSL configuration file with the following contents:

      ```
      $ cat > <example-cloudhsm-openssl.cnf> << 'EOF'
      ## NOTE: This should point to the system default openssl config file.
      # Replace /etc/pki/tls with the path to your OpenSSL configuration directory
      .include </etc/pki/tls>/openssl.cnf
      
      # Override the existing provider_section to include AWS CloudHSM OpenSSL Provider as a 3rd party OpenSSL provider
      [provider_sect]
      default = default_sect
      # Include AWS CloudHSM CloudHSM OpenSSL provider
      cloudhsm = cloudhsm_sect
      
      [default_sect]
      activate = 1
      
      [cloudhsm_sect]
      activate = 1
      EOF
      ```

   1. Ensure that the `CLOUDHSM_PIN` environment variable is set with your crypto user (CU) credentials:

      ```
      $ export CLOUDHSM_PIN=<username>:<password>
      ```

   1. Set the `OPENSSL_CONF` environment variable to point to your updated configuration file and verify the provider is loaded:

      ```
      $ OPENSSL_CONF=/path/to/example-cloudhsm-openssl.cnf openssl list -providers
      ```

      You should see both the default provider and the CloudHSM provider listed:

      ```
      OPENSSL_CONF=/path/to/example-cloudhsm-openssl.cnf openssl list -providers
      Providers:
        default
          name: OpenSSL Default Provider
          version: 3.2.2
          status: active
        cloudhsm
          name: AWS CloudHSM OpenSSL Provider
          version: 5.17.0
          status: active
      ```

1. Run the following command to back up the `/etc/nginx/nginx.conf` file.

   ```
   $ cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
   ```

1. Update the NGINX configuration.
**Note**  
Each cluster can support a maximum of 1000 NGINX worker processes across all NGINX web servers.

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

   Use a text editor to edit the `/etc/nginx/nginx.conf` file. This may require Linux root permissions. At the top of the file, add the following lines: 

   ```
   env CLOUDHSM_PIN;
   env OPENSSL_CONF;
   ```

   Then add the following to the TLS section of the file:

   ```
   # Settings for a TLS enabled server.
   server {
       listen       443 ssl http2 default_server;
       listen       [::]:443 ssl http2 default_server;
       server_name  _;
       root         /usr/share/nginx/html;
   
       ssl_certificate "/etc/pki/nginx/server.crt";
       ssl_certificate_key "/etc/pki/nginx/private/server.key";
       # It is *strongly* recommended to generate unique DH parameters for DHE ciphers
       # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
       # ssl_dhparam "/etc/pki/nginx/dhparams.pem";
       ssl_session_cache shared:SSL:1m;
       ssl_session_timeout  10m;
       ssl_protocols TLSv1.2 TLSv1.3;
       ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256";
       ssl_prefer_server_ciphers off;
   
       # Load configuration files for the default server block.
       include /etc/nginx/default.d/*.conf;
   
       location / {
       }
   
       error_page 404 /404.html;
       location = /40x.html {
       }
   
       error_page 500 502 503 504 /50x.html;
       location = /50x.html {
       }
   }
   ```

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

   Use a text editor to edit the `/etc/nginx/nginx.conf` file. This may require Linux root permissions. At the top of the file, add the following lines: 

   ```
   env CLOUDHSM_PIN;
   env OPENSSL_CONF;
   ```

   Then add the following to the TLS section of the file:

   ```
   # Settings for a TLS enabled server.
   server {
       listen       443 ssl http2 default_server;
       listen       [::]:443 ssl http2 default_server;
       server_name  _;
       root         /usr/share/nginx/html;
   
       ssl_certificate "/etc/pki/nginx/server.crt";
       ssl_certificate_key "/etc/pki/nginx/private/server.key";
       # It is *strongly* recommended to generate unique DH parameters for DHE ciphers
       # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
       # ssl_dhparam "/etc/pki/nginx/dhparams.pem";
       ssl_session_cache shared:SSL:1m;
       ssl_session_timeout  10m;
       ssl_protocols TLSv1.2 TLSv1.3;
       ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256";
       ssl_prefer_server_ciphers off;
   
       # Load configuration files for the default server block.
       include /etc/nginx/default.d/*.conf;
   
       location / {
       }
   
       error_page 404 /404.html;
       location = /40x.html {
       }
   
       error_page 500 502 503 504 /50x.html;
       location = /50x.html {
       }
   }
   ```

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

   Use a text editor to edit the `/etc/nginx/nginx.conf` file. This may require Linux root permissions. At the top of the file, add the following lines: 

   ```
   env CLOUDHSM_PIN;
   env OPENSSL_CONF;
   ```

   Then add the following to the TLS section of the file:

   ```
   # Settings for a TLS enabled server.
   server {
       listen       443 ssl http2 default_server;
       listen       [::]:443 ssl http2 default_server;
       server_name  _;
       root         /usr/share/nginx/html;
   
       ssl_certificate "/etc/pki/nginx/server.crt";
       ssl_certificate_key "/etc/pki/nginx/private/server.key";
       # It is *strongly* recommended to generate unique DH parameters for DHE ciphers
       # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
       # ssl_dhparam "/etc/pki/nginx/dhparams.pem";
       ssl_session_cache shared:SSL:1m;
       ssl_session_timeout  10m;
       ssl_protocols TLSv1.2 TLSv1.3;
       ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256";
       ssl_prefer_server_ciphers off;
   
       # Load configuration files for the default server block.
       include /etc/nginx/default.d/*.conf;
   
       location / {
       }
   
       error_page 404 /404.html;
       location = /40x.html {
       }
   
       error_page 500 502 503 504 /50x.html;
       location = /50x.html {
       }
   }
   ```

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

   Use a text editor to edit the `/etc/nginx/nginx.conf` file. This may require Linux root permissions. At the top of the file, add the following lines: 

   ```
   env CLOUDHSM_PIN;
   env OPENSSL_CONF;
   ```

   Then add the following to the TLS section of the file:

   ```
   # Settings for a TLS enabled server.
   server {
       listen       443 ssl http2 default_server;
       listen       [::]:443 ssl http2 default_server;
       server_name  _;
       root         /var/www/html;
   
       ssl_certificate "/etc/ssl/certs/server.crt";
       ssl_certificate_key "/etc/ssl/private/server.key";
       # It is *strongly* recommended to generate unique DH parameters for DHE ciphers
       # Generate them with: openssl dhparam -out /etc/ssl/certs/dhparams.pem 2048
       # ssl_dhparam "/etc/ssl/certs/dhparams.pem";
       ssl_session_cache shared:SSL:1m;
       ssl_session_timeout  10m;
       ssl_protocols TLSv1.2 TLSv1.3;
       ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256";
       ssl_prefer_server_ciphers off;
   
       # Load configuration files for the default server block.
       include /etc/nginx/default.d/*.conf;
   
       location / {
       }
   
       error_page 404 /404.html;
       location = /40x.html {
       }
   
       error_page 500 502 503 504 /50x.html;
       location = /50x.html {
       }
   }
   ```

------

   Save the file.

1. Back up the `systemd` configuration file, and then set the `EnvironmentFile` path.

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

   1. Back up the `nginx.service` file:

      ```
      $ cp /lib/systemd/system/nginx.service /lib/systemd/system/nginx.service.backup
      ```

   1. Open `/lib/systemd/system/nginx.service` in a text editor. Under the [Service] section, add:

      ```
      EnvironmentFile=/etc/sysconfig/nginx
      ```

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

   1. Back up the `nginx.service` file:

      ```
      $ cp /lib/systemd/system/nginx.service /lib/systemd/system/nginx.service.backup
      ```

   1. Open `/lib/systemd/system/nginx.service` in a text editor. Under the [Service] section, add:

      ```
      EnvironmentFile=/etc/sysconfig/nginx
      ```

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

   1. Back up the `nginx.service` file:

      ```
      $ cp /lib/systemd/system/nginx.service /lib/systemd/system/nginx.service.backup
      ```

   1. Open `/lib/systemd/system/nginx.service` in a text editor. Under the [Service] section, add:

      ```
      EnvironmentFile=/etc/sysconfig/nginx
      ```

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

   1. Back up the `nginx.service` file:

      ```
      $ cp /lib/systemd/system/nginx.service /lib/systemd/system/nginx.service.backup
      ```

   1. Open `/lib/systemd/system/nginx.service` in a text editor. Under the [Service] section, add:

      ```
      EnvironmentFile=/etc/sysconfig/nginx
      ```

------

1.  Check if the `/etc/sysconfig/nginx` file exists, and then do one of the following: 
   + If the file exists, back up the file by running the following command:

     ```
     $ cp /etc/sysconfig/nginx /etc/sysconfig/nginx.backup
     ```
   +  If the file doesn't exist, open a text editor, and then create a file named `nginx` in the `/etc/sysconfig/` folder. 

1. Configure the NGINX environment.

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

   As the Linux root user, open `/etc/sysconfig/nginx` file in a text editor. For example,

   ```
   vi /etc/sysconfig/nginx
   ```

   Add the Cryptography User (CU) credentials and the path to your OpenSSL configuration file:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   OPENSSL_CONF=<path to example-cloudhsm-openssl.cnf>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials. Replace *<path to example-cloudhsm-openssl.cnf>* with the full path to the configuration file you created in [To configure NGINX for OpenSSL Provider](#configure-nginx-provider).

    Save the file.

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

   Open the `/etc/sysconfig/nginx` file in a text editor. This may require Linux root permissions. Add the Cryptography User (CU) credentials and the path to your OpenSSL configuration file:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   OPENSSL_CONF=<path to example-cloudhsm-openssl.cnf>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials. Replace *<path to example-cloudhsm-openssl.cnf>* with the full path to the configuration file you created in [To configure NGINX for OpenSSL Provider](#configure-nginx-provider).

    Save the file.

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

   Open the `/etc/sysconfig/nginx` file in a text editor. This may require Linux root permissions. Add the Cryptography User (CU) credentials and the path to your OpenSSL configuration file:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   OPENSSL_CONF=<path to example-cloudhsm-openssl.cnf>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials. Replace *<path to example-cloudhsm-openssl.cnf>* with the full path to the configuration file you created in [To configure NGINX for OpenSSL Provider](#configure-nginx-provider).

    Save the file.

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

   Open the `/etc/sysconfig/nginx` file in a text editor. This may require Linux root permissions. Add the Cryptography User (CU) credentials and the path to your OpenSSL configuration file:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   OPENSSL_CONF=<path to example-cloudhsm-openssl.cnf>
   ```

   Replace *<CU user name>* and *<password>* with the CU credentials. Replace *<path to example-cloudhsm-openssl.cnf>* with the full path to the configuration file you created in [To configure NGINX for OpenSSL Provider](#configure-nginx-provider).

    Save the file.

------

1. Start the NGINX web server.

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

   Stop all NGINX processes

   ```
   $ systemctl stop nginx
   ```

   Reload the `systemd` configuration to pick up the latest changes

   ```
   $ systemctl daemon-reload
   ```

   Start NGINX

   ```
   $ systemctl start nginx
   ```

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

   Stop any running NGINX process

   ```
   $ systemctl stop nginx
   ```

   Reload the `systemd` configuration to pick up the latest changes

   ```
   $ systemctl daemon-reload
   ```

   Start the NGINX process

   ```
   $ systemctl start nginx
   ```

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

   Stop any running NGINX process

   ```
   $ systemctl stop nginx
   ```

   Reload the `systemd` configuration to pick up the latest changes

   ```
   $ systemctl daemon-reload
   ```

   Start the NGINX process

   ```
   $ systemctl start nginx
   ```

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

   Stop any running NGINX process

   ```
   $ systemctl stop nginx
   ```

   Reload the `systemd` configuration to pick up the latest changes

   ```
   $ systemctl daemon-reload
   ```

   Start the NGINX process

   ```
   $ systemctl start nginx
   ```

------

After you configure NGINX, go to [Verify that HTTPS uses the certificate that you configured](#ssl-offload-verify-https-connection-linux).

### Configure HAProxy web server
<a name="ssl-offload-provider-configure-haproxy"></a>

Use this section to configure HAProxy with the OpenSSL Provider. The following examples show how to set up HAProxy with your CloudHSM certificates and keys.<a name="configure-haproxy-provider"></a>

**To configure HAProxy for OpenSSL Provider**

1. Back up the existing combined certificate file if it exists:

   ```
   $ cp server-combined.pem server-combined.pem.backup
   ```

1. Create a combined certificate file for HAProxy using your certificate and CloudHSM fake PEM key:

   ```
   $ cat server.crt server.key > server-combined.pem
   ```

1. Back up the existing HAProxy configuration:

   ```
   $ cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup
   ```

1. Create a new CloudHSM TLS offload configuration at `/etc/haproxy/haproxy.cfg`:

   ```
   global
       daemon
       ssl-provider cloudhsm
       # It is *strongly* recommended to generate unique DH parameters
       # Generate them with: openssl dhparam -out /etc/haproxy/dhparams.pem 2048
       # ssl-dh-param-file /etc/haproxy/dhparams.pem
       ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305
       ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
       ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
   
   defaults
       mode http
       timeout connect 5000ms
       timeout client 50000ms
       timeout server 50000ms
   
   frontend haproxy_frontend
       bind *:443 ssl crt /path/to/server-combined.pem
       default_backend web_servers
   
   backend web_servers
       server web1 127.0.0.1:8080 check
   ```

   Update the certificate path to match your file location.

1. Configure systemd to use an environment file for HAProxy. The location depends on your Linux distribution.

------
#### [ Amazon Linux and RHEL ]

   Back up and modify the HAProxy service file:

   ```
   $ cp /lib/systemd/system/haproxy.service /lib/systemd/system/haproxy.service.backup
   ```

   Edit `/lib/systemd/system/haproxy.service` and add the following line under the [Service] section:

   ```
   EnvironmentFile=/etc/sysconfig/haproxy
   ```

------
#### [ Ubuntu ]

   Back up and modify the HAProxy service file:

   ```
   $ cp /lib/systemd/system/haproxy.service /lib/systemd/system/haproxy.service.backup
   ```

   Edit `/lib/systemd/system/haproxy.service` and add the following line under the [Service] section:

   ```
   EnvironmentFile=/etc/default/haproxy
   ```

------

1. Create the environment file in the appropriate location for your system.

------
#### [ Amazon Linux and RHEL ]

   Back up the HAProxy environment file if it exists:

   ```
   $ cp /etc/sysconfig/haproxy /etc/sysconfig/haproxy.backup
   ```

   Create the HAProxy environment file `/etc/sysconfig/haproxy` with the following contents:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

------
#### [ Ubuntu ]

   Back up the HAProxy environment file if it exists:

   ```
   $ cp /etc/default/haproxy /etc/default/haproxy.backup
   ```

   Create the HAProxy environment file `/etc/default/haproxy` with the following contents:

   ```
   CLOUDHSM_PIN=<CU user name>:<password>
   ```

------

   Replace *<CU user name>* and *<password>* with your CU credentials.

1. Reload systemd configuration:

   ```
   $ systemctl daemon-reload
   ```

1. Start HAProxy with the CloudHSM TLS offload configuration:

   ```
   $ systemctl start haproxy
   ```

   You can also run HAProxy directly with a custom configuration file:

   ```
   $ haproxy -f /path/to/haproxy-cloudhsm.cfg
   ```

After you configure HAProxy, go to [Verify that HTTPS uses the certificate that you configured](#ssl-offload-verify-https-connection-linux).

## Step 4: Enable HTTPS traffic and verify the certificate
<a name="ssl-offload-enable-traffic-and-verify-certificate-provider"></a>

After you configure your web server for SSL/TLS offload with AWS CloudHSM, add your web server instance to a security group that allows inbound HTTPS traffic. This allows clients, such as web browsers, to establish an HTTPS connection with your web server. Then make an HTTPS connection to your web server and verify that it's using the certificate that you configured for SSL/TLS offload with AWS CloudHSM.

**Topics**
+ [

### Enable inbound HTTPS connections
](#ssl-offload-add-security-group-linux)
+ [

### Verify that HTTPS uses the certificate that you configured
](#ssl-offload-verify-https-connection-linux)

### Enable inbound HTTPS connections
<a name="ssl-offload-add-security-group-linux"></a>

To connect to your web server from a client (such as a web browser), create a security group that allows inbound HTTPS connections. Specifically, it should allow inbound TCP connections on port 443. Assign this security group to your web server. 

**To create a security group for HTTPS and assign it to your web server**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. Choose **Security groups** in the navigation pane.

1. Choose **Create security group**.

1. For **Create Security Group**, do the following:

   1. For **Security group name**, type a name for the security group that you are creating.

   1. (Optional) Type a description of the security group that you are creating.

   1. For **VPC**, choose the VPC that contains your web server Amazon EC2 instance.

   1. Select **Add Rule**.

   1. For **Type**, select **HTTPS** from the drop-down window.

   1. For **Source**, enter a source location.

   1. Choose **Create security group**.

1. In the navigation pane, choose **Instances**.

1. Select the check box next to your web server instance.

1. Select the **Actions** drop-down menu at the top of the page. Select **Security** and then **Change Security Groups**.

1. For **Associated security groups**, select the search box and choose the security group that you created for HTTPS. Then choose **Add Security Groups**.

1. Select **Save**. 

### Verify that HTTPS uses the certificate that you configured
<a name="ssl-offload-verify-https-connection-linux"></a>

After you add the web server to a security group, you can verify that SSL/TLS offload is using your self-signed certificate. You can do this with a web browser or with a tool such as [OpenSSL s\$1client](https://www.openssl.org/docs/manmaster/man1/s_client.html).

**To verify SSL/TLS offload with a web browser**

1. Use a web browser to connect to your web server using the public DNS name or IP address of the server. Ensure that the URL in the address bar begins with https://. For example, **https://ec2-52-14-212-67.us-east-2.compute.amazonaws.com/**.
**Tip**  
You can use a DNS service such as Amazon Route 53 to route your website's domain name (for example, https://www.example.com/) to your web server. For more information, see [Routing Traffic to an Amazon EC2 Instance](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html) in the *Amazon Route 53 Developer Guide* or in the documentation for your DNS service.

1. Use your web browser to view the web server certificate. For more information, see the following:
   + For Mozilla Firefox, see [View a Certificate](https://support.mozilla.org/en-US/kb/secure-website-certificate#w_view-a-certificate) on the Mozilla Support website.
   + For Google Chrome, see [Understand Security Issues](https://developers.google.com/web/tools/chrome-devtools/security) on the Google Tools for Web Developers website.

   Other web browsers might have similar features that you can use to view the web server certificate.

1. Ensure that the SSL/TLS certificate is the one that you configured your web server to use.

**To verify SSL/TLS offload with OpenSSL s\$1client**

1. Run the following OpenSSL command to connect to your web server using HTTPS. Replace *<server name>* with the public DNS name or IP address of your web server. 

   ```
   openssl s_client -connect <server name>:443
   ```
**Tip**  
You can use a DNS service such as Amazon Route 53 to route your website's domain name (for example, https://www.example.com/) to your web server. For more information, see [Routing Traffic to an Amazon EC2 Instance](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html) in the *Amazon Route 53 Developer Guide* or in the documentation for your DNS service.

1. Ensure that the SSL/TLS certificate is the one that you configured your web server to use.

You now have a website that is secured with HTTPS. The private key for the web server is stored in an HSM in your AWS CloudHSM cluster. 

To add a load balancer, see [Add a load balancer with Elastic Load Balancing for AWS CloudHSM(optional)](third-offload-add-lb.md).

# AWS CloudHSM SSL/TLS offload on Linux using Tomcat with JSSE
<a name="third-offload-linux-jsse"></a>

This topic provides step-by-step instructions for setting up SSL/TLS offload using Java Secure Socket Extension (JSSE) with the AWS CloudHSM JCE SDK.

**Topics**
+ [

## Overview
](#third-offload-linux-jsse-overview)
+ [

## Step 1: Set up the prerequisites
](#third-offload-linux-jsse-prereqs)
+ [

## Step 2: Generate or import a private key and SSL/TLS certificate
](#third-offload-linux-jsse-gen)
+ [

## Step 3: Configure the Tomcat web server
](#third-offload-linux-jsse-config)
+ [

## Step 4: Enable HTTPS traffic and verify the certificate
](#third-offload-linux-jsse-verify)

## Overview
<a name="third-offload-linux-jsse-overview"></a>

 In AWS CloudHSM, Tomcat web servers work on Linux to support HTTPS. The AWS CloudHSM JCE SDK provides an interface that can be used with JSSE (Java Secure Socket Extension) to enable use of HSMs for such web servers. AWS CloudHSM JCE is the bridge that connects JSSE to your AWS CloudHSM cluster. JSSE is a Java API for Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols. 

## Step 1: Set up the prerequisites
<a name="third-offload-linux-jsse-prereqs"></a>

Follow these prerequisites to use a Tomcat web server with AWS CloudHSM for SSL/TLS offload on Linux. These prerequisites must be met to set up web server SSL/TLS offload with Client SDK 5 and a Tomcat web server.

**Note**  
Different platforms require different prerequisites. Always follow the correct installation steps for your platform.

### Prerequisites
<a name="new-versions-jsse"></a>
+ An Amazon EC2 instance running a Linux operating system with A tomcat web server installed.
+ A [crypto user](understanding-users.md#crypto-user-chsm-cli) (CU) to own and manage the web server's private key on the HSM.
+ An active AWS CloudHSM cluster with at least two hardware security modules (HSMs) that have [JCE for Client SDK 5](java-library-install_5.md) installed and configured.
**Note**  
You can use a single HSM cluster, but you must first disable client key durability. For more information, see [Manage Client Key Durability Settings](working-client-sync.md#client-sync-sdk8) and [Client SDK 5 Configure Tool](configure-sdk-5.md).

#### How to meet the prerequisites
<a name="jsse-prereqs-how-to"></a>

1. Install and configure the JCE for AWS CloudHSM on an active AWS CloudHSM cluster with at least two hardware security modules (HSMs). For more information about installation, see [JCE for Client SDK 5](java-library-install_5.md).

1. On an EC2 Linux instance that has access to your AWS CloudHSM cluster, follow the [Apache Tomcat instructions](https://tomcat.apache.org/download-90.cgi ) to download and install the Tomcat web server.

1. Use [CloudHSM CLI](cloudhsm_cli.md) to create a crypto user (CU). For more information about managing HSM users, see [Managing HSM users with CloudHSM CLI](manage-hsm-users-chsm-cli.md). 
**Tip**  
Keep track of the CU user name and password. You will need them later when you generate or import the HTTPS private key and certificate for your web server.

1. To setup JCE with Java Keytool, follow the instructions in [Use Client SDK 5 to integrate AWS CloudHSM with Java Keytool and Jarsigner](keystore-third-party-tools_5.md).

After you complete these steps, go to [Step 2: Generate or import a private key and SSL/TLS certificate](#third-offload-linux-jsse-gen).

#### Notes
<a name="jsse-prereqs-notes"></a>
+ To use Security-Enhanced Linux (SELinux) and web servers, you must allow outbound TCP connections on port 2223, which is the port Client SDK 5 uses to communicate with the HSM.
+ To create and activate a cluster and give an EC2 instance access to the cluster, complete the steps in [Getting Started with AWS CloudHSM](getting-started.md). This section offers step-by-step instructions for creating an active cluster with one HSM and an Amazon EC2 client instance. You can use this client instance as your web server. 
+ To avoid disabling client key durability, add more than one HSM to your cluster. For more information, see [Adding an HSM to an AWS CloudHSM cluster](add-hsm.md).
+ To connect to your client instance, you can use SSH or PuTTY. For more information, see [Connecting to Your Linux Instance Using SSH](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html) or [Connecting to Your Linux Instance from Windows Using PuTTY](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html) in the Amazon EC2 documentation. 

## Step 2: Generate or import a private key and SSL/TLS certificate
<a name="third-offload-linux-jsse-gen"></a>

To enable HTTPS, your Tomcat web server application needs a private key and a corresponding SSL/TLS certificate. To use web server SSL/TLS offload with AWS CloudHSM, you must store the private key in an HSM in your AWS CloudHSM cluster. 

**Note**  
If you don't yet have a private key and a corresponding certificate, generate a private key in an HSM. You use the private key to create a certificate signing request (CSR), which you use to create the SSL/TLS certificate.

You create a local AWS CloudHSM KeyStore file that contains a reference to your private key on the HSM and the associated certificate. Your web server uses the AWS CloudHSM KeyStore file to identify the private key on the HSM during SSL/TLS offload.

**Topics**
+ [

### Generate a private key
](#jsse-ssl-offload-generate-private-key)
+ [

### Generate a self-signed certificate
](#jsse-ssl-offload-generate-certificate)

### Generate a private key
<a name="jsse-ssl-offload-generate-private-key"></a>

This section shows you how to generate a key pair using the KeyTool from JDK. Once you have a key pair generated inside the HSM, you can export it as a KeyStore file, and generate the corresponding certificate.

Depending on your use case, you can either generate an RSA or an EC key pair. The following steps show how to generate an RSA key pair.

**Use the `genkeypair` command in KeyTool to generate an RSA key pair**

1. After replacing the *<VARIABLES>* below with your specific data, use the following command to generate a keystore file named `jsse_keystore.keystore`, which will have a reference of your private key on the HSM.

   ```
   $ keytool -genkeypair -alias <UNIQUE ALIAS FOR KEYS> -keyalg <KEY ALGORITHM> -keysize <KEY SIZE> -sigalg <SIGN ALGORITHM> \
           -keystore <PATH>/<JSSE KEYSTORE NAME>.keystore -storetype CLOUDHSM \
           -dname CERT_DOMAIN_NAME \
           -J-classpath '-J'$JAVA_LIB'/*:/opt/cloudhsm/java/*:./*' \
           -provider "com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider" \
           -providerpath "$CLOUDHSM_JCE_LOCATION" \
           -keypass <KEY PASSWORD> -storepass <KEYSTORE PASSWORD>
   ```
   + ***<PATH>***: The path that you want to generate your keystore file.
   + ***<UNIQUE ALIAS FOR KEYS>***: This is used to uniquely identify your key on the HSM. This alias will be set as the LABEL attribute for the key.
   + ***<KEY PASSWORD>***: We store reference to your key in the local keystore file, and this password protects that local reference.
   + ***<KEYSTORE PASSWORD>***: This is the password for your local keystore file.
   + ***<JSSE KEYSTORE NAME>***: Name of the Keystore file.
   + ***<CERT DOMAIN NAME>***: X.500 Distinguished name.
   + ***<KEY ALGORITHM>***: Key algorithm to generate key pair (For example, RSA and EC).
   + ***<KEY SIZE>***: Key size to generate key pair (for example, 2048, 3072, and 4096).
   + ***<SIGN ALGORITHM>***: Key size to generate key pair (for example, SHA1withRSA, SHA224withRSA, SHA256withRSA, SHA384withRSA, and SHA512withRSA).

1. To confirm the command was successful, enter the following command and verify you have successfully generated an RSA key pair.

   ```
   $ ls <PATH>/<JSSE KEYSTORE NAME>.keystore
   ```

### Generate a self-signed certificate
<a name="jsse-ssl-offload-generate-certificate"></a>

Once you have generated a private key along with the keystore file, you can use this file to generate a certificate signing request (CSR) and certificate.

In a production environment, you typically use a certificate authority (CA) to create a certificate from a CSR. A CA is not necessary for a test environment. If you do use a CA, send the CSR file to them and use signed SSL/TLS certificate that they provide you in your web server for HTTPS.

As an alternative to using a CA, you can use the KeyTool to create a self-signed certificate. Self-signed certificates are not trusted by browsers and should not be used in production environments. They can be used in test environments.

**Warning**  
Self-signed certificates should be used in a test environment only. For a production environment, use a more secure method, such as a certificate authority to create a certificate.

**Topics**<a name="jsse-ssl-procedure-offload-generate-certificate"></a>

**Generate a certificate**

1. Obtain a copy of your keystore file generated in an earlier step.

1. Run the following command to use the KeyTool to create a certificate signing request (CSR).

   ```
   $ keytool -certreq -keyalg RSA -alias unique_alias_for_key -file certreq.csr \
           -keystore <JSSE KEYSTORE NAME>.keystore -storetype CLOUDHSM \
           -J-classpath '-J$JAVA_LIB/*:/opt/cloudhsm/java/*:./*' \
           -keypass <KEY PASSWORD> -storepass <KEYSTORE PASSWORD>
   ```
**Note**  
The output file of the certificate signing request is `certreq.csr`.<a name="jsse-ssl-procedure-offload-sign-certificate"></a>

**Sign a certificate**
+ After replacing the *<VARIABLES>* below with your specific data, run the following command to sign your CSR with your private key on your HSM. This creates a self-signed certificate.

  ```
  $ keytool -gencert -infile certreq.csr -outfile certificate.crt \
      -alias <UNIQUE ALIAS FOR KEYS> -keypass <KEY_PASSWORD> -storepass <KEYSTORE_PASSWORD> -sigalg SIG_ALG \
      -storetype CLOUDHSM -J-classpath '-J$JAVA_LIB/*:/opt/cloudhsm/java/*:./*' \
      -keystore jsse_keystore.keystore
  ```
**Note**  
`certificate.crt` is the signed certificate that uses the alias’s private key.<a name="jsse-ssl-procedure-offload-import-certificate"></a>

**Import a certificate in Keystore**
+ After replacing the *<VARIABLES>* below with your specific data, run the following command to import a signed certificate as a trusted certificate. This step will store the certificate in the keystore entry identified by alias.

  ```
  $ keytool -import -alias <UNIQUE ALIAS FOR KEYS> -keystore jsse_keystore.keystore \
      -file certificate.crt -storetype CLOUDHSM \
      -v -J-classpath '-J$JAVA_LIB/*:/opt/cloudhsm/java/*:./*' \
      -keypass <KEY PASSWORD> -storepass <KEYSTORE_PASSWORD>
  ```<a name="jsse-ssl-procedure-offload-convert-certificate"></a>

**Convert a certificate to a PEM**
+ Run following command to convert the signed certificate file (`.crt`) to a PEM. The PEM file will be used to send the request from the http client.

  ```
  $ openssl x509 -inform der -in certificate.crt -out certificate.pem
  ```

After you complete these steps, go to [Step 3: Configure the web server](#third-offload-linux-jsse-config).

## Step 3: Configure the Tomcat web server
<a name="third-offload-linux-jsse-config"></a>

Update your web server software's configuration to use the HTTPS certificate and corresponding PEM file that you created in the previous step. Remember to backup your existing certificates and keys before you start. This will finish setting up your Linux web server software for SSL/TLS offload with AWS CloudHSM. For more information, refer to the [Apache Tomcat 9 Configuration Reference](https://tomcat.apache.org/tomcat-9.0-doc/config/http.html).<a name="jsse-config-stop-server"></a>

**Stop the server**
+ After replacing the *<VARIABLES>* below with your specific data, run following command to stop Tomcat Server before updating configuration

  ```
  $ /<TOMCAT DIRECTORY>/bin/shutdown.sh
  ```
  + ***<TOMCAT DIRECTORY>***: Your Tomcat installation directory.<a name="jsse-config-update-class-path"></a>

**Update the Tomcat classpath**

1. Connect to your client instance.

1. Locate the Tomcat installation folder.

1. After replacing the *<VARIABLES>* below with your specific data, use the following command to add Java library and AWS CloudHSM Java path in Tomcat **classpath**, located in Tomcat/bin/catalina.sh file.

   ```
   $ sed -i 's@CLASSPATH="$CLASSPATH""$CATALINA_HOME"\/bin\/bootstrap.jar@CLASSPATH="$CLASSPATH""$CATALINA_HOME"\/bin\/bootstrap.jar:'"
           <JAVA LIBRARY>"'\/*:\/opt\/cloudhsm\/java\/*:.\/*@' <TOMCAT PATH> /bin/catalina.sh
   ```
   + ***<JAVA LIBRARY>***: Java JRE Library location.
   + ***<TOMCAT PATH>***: Tomcat installation folder.<a name="jsse-config-add-https"></a>

**Add an HTTPS connector in the server configuration.**

1. Go to the Tomcat installation folder.

1. After replacing the *<VARIABLES>* below with your specific data, use the following command to add an HTTPS connector to use certificates generated in prerequisites:

   ```
   $ sed -i '/<Connector port="8080"/i <Connector port=\"443\" maxThreads=\"200\" scheme=\"https\" secure=\"true\" SSLEnabled=\"true\" keystoreType=\"CLOUDHSM\" keystoreFile=\"
           <CUSTOM DIRECTORY>/<JSSE KEYSTORE NAME>.keystore\" keystorePass=\"<KEYSTORE PASSWORD>\" keyPass=\"<KEY PASSWORD>
           \" keyAlias=\"<UNIQUE ALIAS FOR KEYS>" clientAuth=\"false\" sslProtocol=\"TLS\"/>' <TOMCAT PATH>/conf/server.xml
   ```
   + ***<CUSTOM DIRECTORY>***: Directory where keystore file is located.
   + ***<JSSE KEYSTORE NAME>***: Name of the Keystore file.
   + ***<KEYSTORE PASSWORD>***: This is the password for your local keystore file.
   + ***<KEY PASSWORD>***: We store reference to your key in the local keystore file, and this password protects that local reference.
   + ***<UNIQUE ALIAS FOR KEYS>***: This is used to uniquely identify your key on the HSM. This alias will be set as the LABEL attribute for the key.
   + ***<TOMCAT PATH>***: The path to your Tomcat folder.<a name="jsse-config-start-server"></a>

**Start Server**
+ After replacing the *<VARIABLES>* below with your specific data, use the following command to start Tomcat Server:

  ```
  $ /<TOMCAT DIRECTORY>/bin/startup.sh
  ```
**Note**  
***<TOMCAT DIRECTORY>*** is the name of your Tomcat installation directory.

After you update your web server configuration, go to [Step 4: Enable HTTPS traffic and verify the certificate](#third-offload-linux-jsse-verify).

## Step 4: Enable HTTPS traffic and verify the certificate
<a name="third-offload-linux-jsse-verify"></a>

After you configure your web server for SSL/TLS offload with AWS CloudHSM, add your web server instance to a security group that allows inbound HTTPS traffic. This allows clients, such as web browsers, to establish an HTTPS connection with your web server. Then make an HTTPS connection to your web server and verify that it's using the certificate that you configured for SSL/TLS offload with AWS CloudHSM.

**Topics**
+ [

### Enable inbound HTTPS connections
](#jsse-linux-add-security-group)
+ [

### Verify that HTTPS uses the certificate that you configured
](#jsse-linux-verify-https-connection)

### Enable inbound HTTPS connections
<a name="jsse-linux-add-security-group"></a>

To connect to your web server from a client (such as a web browser), create a security group that allows inbound HTTPS connections. Specifically, it should allow inbound TCP connections on port 443. Assign this security group to your web server. 

**To create a security group for HTTPS and assign it to your web server**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. Choose **Security groups** in the navigation pane.

1. Choose **Create security group**.

1. For **Create Security Group**, do the following:

   1. For **Security group name**, type a name for the security group that you are creating.

   1. (Optional) Type a description of the security group that you are creating.

   1. For **VPC**, choose the VPC that contains your web server Amazon EC2 instance.

   1. Select **Add Rule**.

   1. For **Type**, select **HTTPS** from the drop-down window.

   1. For **Source**, enter a source location.

   1. Choose **Create security group**.

1. In the navigation pane, choose **Instances**.

1. Select the check box next to your web server instance.

1. Select the **Actions** drop-down menu at the top of the page. Select **Security** and then **Change Security Groups**.

1. For **Associated security groups**, select the search box and choose the security group that you created for HTTPS. Then choose **Add Security Groups**.

1. Select **Save**. 

### Verify that HTTPS uses the certificate that you configured
<a name="jsse-linux-verify-https-connection"></a>

After you add the web server to a security group, you can verify that SSL/TLS offload is using your self-signed certificate. You can do this with a web browser or with a tool such as [OpenSSL s\$1client](https://www.openssl.org/docs/manmaster/man1/s_client.html).

**To verify SSL/TLS offload with a web browser**

1. Use a web browser to connect to your web server using the public DNS name or IP address of the server. Ensure that the URL in the address bar begins with https://. For example, **https://ec2-52-14-212-67.us-east-2.compute.amazonaws.com/**.
**Tip**  
You can use a DNS service such as Amazon Route 53 to route your website's domain name (for example, https://www.example.com/) to your web server. For more information, see [Routing Traffic to an Amazon EC2 Instance](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html) in the *Amazon Route 53 Developer Guide* or in the documentation for your DNS service.

1. Use your web browser to view the web server certificate. For more information, see the following:
   + For Mozilla Firefox, see [View a Certificate](https://support.mozilla.org/en-US/kb/secure-website-certificate#w_view-a-certificate) on the Mozilla Support website.
   + For Google Chrome, see [Understand Security Issues](https://developers.google.com/web/tools/chrome-devtools/security) on the Google Tools for Web Developers website.

   Other web browsers might have similar features that you can use to view the web server certificate.

1. Ensure that the SSL/TLS certificate is the one that you configured your web server to use.

**To verify SSL/TLS offload with OpenSSL s\$1client**

1. Run the following OpenSSL command to connect to your web server using HTTPS. Replace *<server name>* with the public DNS name or IP address of your web server. 

   ```
   openssl s_client -connect <server name>:443
   ```
**Tip**  
You can use a DNS service such as Amazon Route 53 to route your website's domain name (for example, https://www.example.com/) to your web server. For more information, see [Routing Traffic to an Amazon EC2 Instance](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html) in the *Amazon Route 53 Developer Guide* or in the documentation for your DNS service.

1. Ensure that the SSL/TLS certificate is the one that you configured your web server to use.

You now have a website that is secured with HTTPS. The private key for the web server is stored in an HSM in your AWS CloudHSM cluster. 

To add a load balancer, see [Add a load balancer with Elastic Load Balancing for AWS CloudHSM(optional)](third-offload-add-lb.md).

# AWS CloudHSM SSL/TLS offload on Windows using IIS with KSP
<a name="ssl-offload-windows"></a>

This tutorial provides step-by-step instructions for setting up SSL/TLS offload with AWS CloudHSM on a Windows web server.

**Topics**
+ [

## Overview
](#ssl-offload-windows-overview)
+ [

## Step 1: Set up the prerequisites
](#ssl-offload-prerequisites-windows)
+ [

## Step 2: Create a certificate signing request (CSR) and certificate
](#ssl-offload-windows-create-csr-and-certificate)
+ [

## Step 3: Configure the web server
](#ssl-offload-configure-web-server-windows)
+ [

## Step 4: Enable HTTPS traffic and verify the certificate
](#ssl-offload-enable-traffic-and-verify-certificate-windows)

## Overview
<a name="ssl-offload-windows-overview"></a>

On Windows, the [Internet Information Services (IIS) for Windows Server](https://www.iis.net/) web server application natively supports HTTPS. The [AWS CloudHSM key storage provider (KSP) for Microsoft's Cryptography API: Next Generation (CNG)](ksp-library.md) provides the interface that allows IIS to use the HSMs in your cluster for cryptographic offloading and key storage. The AWS CloudHSM KSP is the bridge that connects IIS to your AWS CloudHSM cluster.

This tutorial shows you how to do the following:
+ Install the web server software on an Amazon EC2 instance.
+ Configure the web server software to support HTTPS with a private key stored in your AWS CloudHSM cluster.
+ (Optional) Use Amazon EC2 to create a second web server instance and Elastic Load Balancing to create a load balancer. Using a load balancer can increase performance by distributing the load across multiple servers. It can also provide redundancy and higher availability if one or more servers fail.

When you're ready to get started, go to [Step 1: Set up the prerequisites](#ssl-offload-prerequisites-windows).

## Step 1: Set up the prerequisites
<a name="ssl-offload-prerequisites-windows"></a>

Different platforms require different prerequisites. Use the prerequisites section below that matches your platform.

**Topics**
+ [

### Prerequisites for Client SDK 5
](#ssl-offload-prerequisites-windows-sdk5)
+ [

### Prerequisites for Client SDK 3
](#ssl-offload-prerequisites-windows-sdk3)

### Prerequisites for Client SDK 5
<a name="ssl-offload-prerequisites-windows-sdk5"></a>

To set up web server SSL/TLS offload with AWS CloudHSM, you need the following:
+ An active AWS CloudHSM cluster with at least one HSM.
+ An Amazon EC2 instance running a Windows operating system with the following software installed:
  + The AWS CloudHSM client software for Windows.
  + Internet Information Services (IIS) for Windows Server.
+ A [crypto user](understanding-users.md#crypto-user-chsm-cli) (CU) to own and manage the web server's private key on the HSM.

**Note**  
This tutorial uses Microsoft Windows Server 2019. Microsoft Windows Server 2016 and 2022 is also supported.

**To set up a Windows Server instance and create a CU on the HSM**

1. Complete the steps in [Getting started](getting-started.md). When you launch the Amazon EC2 client, choose a Windows Server 2019 AMI. When you complete these steps, you have an active cluster with at least one HSM. You also have an Amazon EC2 client instance running Windows Server with the AWS CloudHSM client software for Windows installed.

1. (Optional) Add more HSMs to your cluster. For more information, see [Adding an HSM to an AWS CloudHSM cluster](add-hsm.md).

1. Connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. Use CloudHSM CLI to create a crypto user (CU). Keep track of the CU user name and password. You will need them to complete the next step. 
**Note**  
For information on creating a user, see [Managing HSM users with CloudHSM CLI](manage-hsm-users-chsm-cli.md).

1. [Set the login credentials for the HSM](ksp-library-authentication.md), using the CU user name and password that you created in the previous step.

1. In step 5, if you used Windows Credentials Manager to set HSM credentials, download [https://live.sysinternals.com/psexec.exe](https://live.sysinternals.com/psexec.exe) from SysInternals to run the following command as *NT Authority\$1SYSTEM*:

   ```
   psexec.exe -s "C:\Program Files\Amazon\CloudHsm\tools\set_cloudhsm_credentials.exe" --username <USERNAME> --password <PASSWORD>
   ```

   Replace *<USERNAME>* and *<PASSWORD>* with the HSM credentials.

**To install IIS on your Windows Server**

1. If you haven't already done so, connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. On your Windows server, start **Server Manager**.

1. In the **Server Manager** dashboard, choose **Add roles and features**.

1. Read the **Before you begin** information, and then choose **Next**.

1. For **Installation Type**, choose **Role-based or feature-based installation**. Then choose **Next**.

1. For **Server Selection**, choose **Select a server from the server pool**. Then choose **Next**.

1. For **Server Roles**, do the following:

   1. Select **Web Server (IIS)**.

   1. For **Add features that are required for Web Server (IIS)**, choose **Add Features**.

   1. Choose **Next** to finish selecting server roles.

1. For **Features**, accept the defaults. Then choose **Next**.

1. Read the **Web Server Role (IIS)** information. Then choose **Next**.

1. For **Select role services**, accept the defaults or change the settings as preferred. Then choose **Next**.

1. For **Confirmation**, read the confirmation information. Then choose **Install**.

1. After the installation is complete, choose **Close**.

After you complete these steps, go to [Step 2: Create a certificate signing request (CSR) and certificate](#ssl-offload-windows-create-csr-and-certificate).

### Prerequisites for Client SDK 3
<a name="ssl-offload-prerequisites-windows-sdk3"></a>

To set up web server SSL/TLS offload with AWS CloudHSM, you need the following:
+ An active AWS CloudHSM cluster with at least one HSM.
+ An Amazon EC2 instance running a Windows operating system with the following software installed:
  + The AWS CloudHSM client software for Windows.
  + Internet Information Services (IIS) for Windows Server.
+ A [crypto user](understanding-users.md#crypto-user-chsm-cli) (CU) to own and manage the web server's private key on the HSM.

**Note**  
This tutorial uses Microsoft Windows Server 2016. Microsoft Windows Server 2012 is also supported, but Microsoft Windows Server 2012 R2 is not.

**To set up a Windows Server instance and create a CU on the HSM**

1. Complete the steps in [Getting started](getting-started.md). When you launch the Amazon EC2 client, choose a Windows Server 2016 or Windows Server 2012 AMI. When you complete these steps, you have an active cluster with at least one HSM. You also have an Amazon EC2 client instance running Windows Server with the AWS CloudHSM client software for Windows installed.

1. (Optional) Add more HSMs to your cluster. For more information, see [Adding an HSM to an AWS CloudHSM cluster](add-hsm.md).

1. Connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. Use CloudHSM CLI to create a crypto user (CU). Keep track of the CU user name and password. You will need them to complete the next step. 
**Note**  
For information on creating a user, see [Managing HSM users with CloudHSM CLI](manage-hsm-users-chsm-cli.md).

1. [Set the login credentials for the HSM](ksp-library-prereq.md), using the CU user name and password that you created in the previous step.

1. In step 5, if you used Windows Credentials Manager to set HSM credentials, download [https://live.sysinternals.com/psexec.exe](https://live.sysinternals.com/psexec.exe) from SysInternals to run the following command as *NT Authority\$1SYSTEM*:

   ```
   psexec.exe -s "C:\Program Files\Amazon\CloudHsm\tools\set_cloudhsm_credentials.exe" --username <USERNAME> --password <PASSWORD>
   ```

   Replace *<USERNAME>* and *<PASSWORD>* with the HSM credentials.

**To install IIS on your Windows Server**

1. If you haven't already done so, connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. On your Windows server, start **Server Manager**.

1. In the **Server Manager** dashboard, choose **Add roles and features**.

1. Read the **Before you begin** information, and then choose **Next**.

1. For **Installation Type**, choose **Role-based or feature-based installation**. Then choose **Next**.

1. For **Server Selection**, choose **Select a server from the server pool**. Then choose **Next**.

1. For **Server Roles**, do the following:

   1. Select **Web Server (IIS)**.

   1. For **Add features that are required for Web Server (IIS)**, choose **Add Features**.

   1. Choose **Next** to finish selecting server roles.

1. For **Features**, accept the defaults. Then choose **Next**.

1. Read the **Web Server Role (IIS)** information. Then choose **Next**.

1. For **Select role services**, accept the defaults or change the settings as preferred. Then choose **Next**.

1. For **Confirmation**, read the confirmation information. Then choose **Install**.

1. After the installation is complete, choose **Close**.

After you complete these steps, go to [Step 2: Create a certificate signing request (CSR) and certificate](#ssl-offload-windows-create-csr-and-certificate).

## Step 2: Create a certificate signing request (CSR) and certificate
<a name="ssl-offload-windows-create-csr-and-certificate"></a>

To enable HTTPS, your web server needs an SSL/TLS certificate and a corresponding private key. To use SSL/TLS offload with AWS CloudHSM, you store the private key in the HSM in your AWS CloudHSM cluster. To do this, you use the [AWS CloudHSM key storage provider (KSP) for Microsoft's Cryptography API: Next Generation (CNG)](ksp-v3-library.md) to create a certificate signing request (CSR). Then you give the CSR to a certificate authority (CA), which signs the CSR to produce a certificate.

**Topics**
+ [

### Create a CSR with Client SDK 5
](#ssl-offload-windows-create-csr-new-version)
+ [

### Create a CSR with Client SDK 3
](#ssl-offload-windows-create-csr-old-version)
+ [

### Get a signed certificate and import it
](#ssl-offload-windows-create-certificate)

### Create a CSR with Client SDK 5
<a name="ssl-offload-windows-create-csr-new-version"></a>

1. On your Windows Server, use a text editor to create a certificate request file named `IISCertRequest.inf`. The following shows the contents of an example `IISCertRequest.inf` file. For more information about the sections, keys, and values that you can specify in the file, see [Microsoft's documentation](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1#BKMK_New). Do not change the `ProviderName` value.

   ```
   [Version]
   Signature = "$Windows NT$"
   [NewRequest]
   Subject = "CN=example.com,C=US,ST=Washington,L=Seattle,O=ExampleOrg,OU=WebServer"
   HashAlgorithm = SHA256
   KeyAlgorithm = RSA
   KeyLength = 2048
   ProviderName = "CloudHSM Key Storage Provider"
   KeyUsage = 0xf0
   MachineKeySet = True
   [EnhancedKeyUsageExtension]
   OID=1.3.6.1.5.5.7.3.1
   ```

1. Use the [Windows **certreq** command](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1) to create a CSR from the `IISCertRequest.inf` file that you created in the previous step. The following example saves the CSR to a file named `IISCertRequest.csr`. If you used a different file name for your certificate request file, replace *IISCertRequest.inf* with the appropriate file name. You can optionally replace *IISCertRequest.csr* with a different file name for your CSR file.

   ```
   C:\>certreq -new IISCertRequest.inf IISCertRequest.csr
   
   CertReq: Request Created
   ```

   The `IISCertRequest.csr` file contains your CSR. You need this CSR to get a signed certificate.

### Create a CSR with Client SDK 3
<a name="ssl-offload-windows-create-csr-old-version"></a>

1. If you haven't already done so, connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. Use the following command to start the AWS CloudHSM client daemon.

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

   ```
   $ sudo start cloudhsm-client
   ```

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

   ```
   $ sudo service cloudhsm-client start
   ```

------
#### [ CentOS 7 ]

   ```
   $ sudo service cloudhsm-client start
   ```

------
#### [ CentOS 8 ]

   ```
   $ sudo service cloudhsm-client start
   ```

------
#### [ RHEL 7 ]

   ```
   $ sudo service cloudhsm-client start
   ```

------
#### [ RHEL 8 ]

   ```
   $ sudo service cloudhsm-client start
   ```

------
#### [ Ubuntu 16.04 LTS ]

   ```
   $ sudo service cloudhsm-client start
   ```

------
#### [ Ubuntu 18.04 LTS ]

   ```
   $ sudo service cloudhsm-client start
   ```

------
#### [ Windows ]
   + For Windows client 1.1.2\$1:

     ```
     C:\Program Files\Amazon\CloudHSM>net.exe start AWSCloudHSMClient
     ```
   + For Windows clients 1.1.1 and older:

     ```
     C:\Program Files\Amazon\CloudHSM>start "cloudhsm_client" cloudhsm_client.exe C:\ProgramData\Amazon\CloudHSM\data\cloudhsm_client.cfg
     ```

------

1. On your Windows Server, use a text editor to create a certificate request file named `IISCertRequest.inf`. The following shows the contents of an example `IISCertRequest.inf` file. For more information about the sections, keys, and values that you can specify in the file, see [Microsoft's documentation](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1#BKMK_New). Do not change the `ProviderName` value.

   ```
   [Version]
   Signature = "$Windows NT$"
   [NewRequest]
   Subject = "CN=example.com,C=US,ST=Washington,L=Seattle,O=ExampleOrg,OU=WebServer"
   HashAlgorithm = SHA256
   KeyAlgorithm = RSA
   KeyLength = 2048
   ProviderName = "Cavium Key Storage Provider"
   KeyUsage = 0xf0
   MachineKeySet = True
   [EnhancedKeyUsageExtension]
   OID=1.3.6.1.5.5.7.3.1
   ```

1. Use the [Windows **certreq** command](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1) to create a CSR from the `IISCertRequest.inf` file that you created in the previous step. The following example saves the CSR to a file named `IISCertRequest.csr`. If you used a different file name for your certificate request file, replace *IISCertRequest.inf* with the appropriate file name. You can optionally replace *IISCertRequest.csr* with a different file name for your CSR file.

   ```
   C:\>certreq -new IISCertRequest.inf IISCertRequest.csr
           SDK Version: 2.03
   
   CertReq: Request Created
   ```

   The `IISCertRequest.csr` file contains your CSR. You need this CSR to get a signed certificate.

### Get a signed certificate and import it
<a name="ssl-offload-windows-create-certificate"></a>

In a production environment, you typically use a certificate authority (CA) to create a certificate from a CSR. A CA is not necessary for a test environment. If you do use a CA, send the CSR file (`IISCertRequest.csr`) to it and use the CA to create a signed SSL/TLS certificate.

As an alternative to using a CA, you can use a tool like [OpenSSL](https://www.openssl.org/) to create a self-signed certificate.

**Warning**  
Self-signed certificates are not trusted by browsers and should not be used in production environments. They can be used in test environments.

The following procedures show how to create a self-signed certificate and use it to sign your web server's CSR.

**To create a self-signed certificate**

1. Use the following OpenSSL command to create a private key. You can optionally replace *SelfSignedCA.key* with the file name to contain your private key.

   ```
   openssl genrsa -aes256 -out SelfSignedCA.key 2048
   Generating RSA private key, 2048 bit long modulus
   ......................................................................+++
   .........................................+++
   e is 65537 (0x10001)
   Enter pass phrase for SelfSignedCA.key:
   Verifying - Enter pass phrase for SelfSignedCA.key:
   ```

1. Use the following OpenSSL command to create a self-signed certificate using the private key that you created in the previous step. This is an interactive command. Read the on-screen instructions and follow the prompts. Replace *SelfSignedCA.key* with the name of the file that contains your private key (if different). You can optionally replace *SelfSignedCA.crt* with the file name to contain your self-signed certificate.

   ```
   openssl req -new -x509 -days 365 -key SelfSignedCA.key -out SelfSignedCA.crt
   Enter pass phrase for SelfSignedCA.key:
   You are about to be asked to enter information that will be incorporated
   into your certificate request.
   What you are about to enter is what is called a Distinguished Name or a DN.
   There are quite a few fields but you can leave some blank
   For some fields there will be a default value,
   If you enter '.', the field will be left blank.
   -----
   Country Name (2 letter code) [AU]:
   State or Province Name (full name) [Some-State]:
   Locality Name (eg, city) []:
   Organization Name (eg, company) [Internet Widgits Pty Ltd]:
   Organizational Unit Name (eg, section) []:
   Common Name (e.g. server FQDN or YOUR name) []:
   Email Address []:
   ```

**To use your self-signed certificate to sign your web server's CSR**
+ Use the following OpenSSL command to use your private key and self-signed certificate to sign the CSR. Replace the following with the names of the files that contain the corresponding data (if different).
  + *IISCertRequest.csr* – The name of the file that contains your web server's CSR
  + *SelfSignedCA.crt* – The name of the file that contains your self-signed certificate
  + *SelfSignedCA.key* – The name of the file that contains your private key
  + *IISCert.crt* – The name of the file to contain your web server's signed certificate

  ```
  openssl x509 -req -days 365 -in IISCertRequest.csr \
                              -CA SelfSignedCA.crt \
                              -CAkey SelfSignedCA.key \
                              -CAcreateserial \
                              -out IISCert.crt
  Signature ok
  subject=/ST=IIS-HSM/L=IIS-HSM/OU=IIS-HSM/O=IIS-HSM/CN=IIS-HSM/C=IIS-HSM
  Getting CA Private Key
  Enter pass phrase for SelfSignedCA.key:
  ```

After you complete the previous step, you have a signed certificate for your web server (`IISCert.crt`) and a self-signed certificate (`SelfSignedCA.crt`). When you have these files, go to [Step 3: Configure the web server](#ssl-offload-configure-web-server-windows).

## Step 3: Configure the web server
<a name="ssl-offload-configure-web-server-windows"></a>

Update your IIS website's configuration to use the HTTPS certificate that you created at the end of the [previous step](#ssl-offload-windows-create-csr-and-certificate). This will finish setting up your Windows web server software (IIS) for SSL/TLS offload with AWS CloudHSM.

If you used a self-signed certificate to sign your CSR, you must first import the self-signed certificate into the Windows Trusted Root Certification Authorities.

**To import your self-signed certificate into the Windows Trusted Root Certification Authorities**

1. If you haven't already done so, connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. Copy your self-signed certificate to your Windows server.

1. On your Windows Server, open the **Control Panel**.

1. For **Search Control Panel**, type **certificates**. Then choose **Manage computer certificates**.

1. In the **Certificates ‐ Local Computer** window, double-click **Trusted Root Certification Authorities**.

1. Right-click on **Certificates** and then choose **All Tasks**, **Import**.

1. In the **Certificate Import Wizard**, choose **Next**.

1. Choose **Browse**, then find and select your self-signed certificate. If you created your self-signed certificate by following the instructions in the [previous step of this tutorial](#ssl-offload-windows-create-csr-and-certificate), your self-signed certificate is named `SelfSignedCA.crt`. Choose **Open**.

1. Choose **Next**.

1. For **Certificate Store**, choose **Place all certificates in the following store**. Then ensure that **Trusted Root Certification Authorities** is selected for **Certificate store**.

1. Choose **Next** and then choose **Finish**.

**To update the IIS website's configuration**

1. If you haven't already done so, connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. Start the AWS CloudHSM client daemon.

1. Copy your web server's signed certificate—the one that you created at the end of [this tutorial's previous step](#ssl-offload-windows-create-csr-and-certificate)—to your Windows server.

1. On your Windows Server, use the [Windows **certreq** command](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1) to accept the signed certificate, as in the following example. Replace *IISCert.crt* with the name of the file that contains your web server's signed certificate.

   ```
   C:\>certreq -accept IISCert.crt
           SDK Version: 2.03
   ```

1. On your Windows server, start **Server Manager**.

1. In the **Server Manager** dashboard, in the top right corner, choose **Tools**, **Internet Information Services (IIS) Manager**.

1. In the **Internet Information Services (IIS) Manager** window, double-click your server name. Then double-click **Sites**. Select your website.

1. Select **SSL Settings**. Then, on the right side of the window, choose **Bindings**.

1. In the **Site Bindings** window, choose **Add**.

1. For **Type**, choose **https**. For **SSL certificate**, choose the HTTPS certificate that you created at the end of [this tutorial's previous step](#ssl-offload-windows-create-csr-and-certificate).
**Note**  
If you encounter an error during this certificate binding, restart your server and retry this step.

1. Choose **OK**.

After you update your website's configuration, go to [Step 4: Enable HTTPS traffic and verify the certificate](#ssl-offload-enable-traffic-and-verify-certificate-windows).

## Step 4: Enable HTTPS traffic and verify the certificate
<a name="ssl-offload-enable-traffic-and-verify-certificate-windows"></a>

After you configure your web server for SSL/TLS offload with AWS CloudHSM, add your web server instance to a security group that allows inbound HTTPS traffic. This allows clients, such as web browsers, to establish an HTTPS connection with your web server. Then make an HTTPS connection to your web server and verify that it's using the certificate that you configured for SSL/TLS offload with AWS CloudHSM.

**Topics**
+ [

### Enable inbound HTTPS connections
](#ssl-offload-add-security-group-windows)
+ [

### Verify that HTTPS uses the certificate that you configured
](#ssl-offload-verify-https-connection-windows)

### Enable inbound HTTPS connections
<a name="ssl-offload-add-security-group-windows"></a>

To connect to your web server from a client (such as a web browser), create a security group that allows inbound HTTPS connections. Specifically, it should allow inbound TCP connections on port 443. Assign this security group to your web server. 

**To create a security group for HTTPS and assign it to your web server**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. Choose **Security groups** in the navigation pane.

1. Choose **Create security group**.

1. For **Create Security Group**, do the following:

   1. For **Security group name**, type a name for the security group that you are creating.

   1. (Optional) Type a description of the security group that you are creating.

   1. For **VPC**, choose the VPC that contains your web server Amazon EC2 instance.

   1. Select **Add Rule**.

   1. For **Type**, select **HTTPS** from the drop-down window.

   1. For **Source**, enter a source location.

   1. Choose **Create security group**.

1. In the navigation pane, choose **Instances**.

1. Select the check box next to your web server instance.

1. Select the **Actions** drop-down menu at the top of the page. Select **Security** and then **Change Security Groups**.

1. For **Associated security groups**, select the search box and choose the security group that you created for HTTPS. Then choose **Add Security Groups**.

1. Select **Save**. 

### Verify that HTTPS uses the certificate that you configured
<a name="ssl-offload-verify-https-connection-windows"></a>

After you add the web server to a security group, you can verify that SSL/TLS offload is using your self-signed certificate. You can do this with a web browser or with a tool such as [OpenSSL s\$1client](https://www.openssl.org/docs/manmaster/man1/s_client.html).

**To verify SSL/TLS offload with a web browser**

1. Use a web browser to connect to your web server using the public DNS name or IP address of the server. Ensure that the URL in the address bar begins with https://. For example, **https://ec2-52-14-212-67.us-east-2.compute.amazonaws.com/**.
**Tip**  
You can use a DNS service such as Amazon Route 53 to route your website's domain name (for example, https://www.example.com/) to your web server. For more information, see [Routing Traffic to an Amazon EC2 Instance](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html) in the *Amazon Route 53 Developer Guide* or in the documentation for your DNS service.

1. Use your web browser to view the web server certificate. For more information, see the following:
   + For Mozilla Firefox, see [View a Certificate](https://support.mozilla.org/en-US/kb/secure-website-certificate#w_view-a-certificate) on the Mozilla Support website.
   + For Google Chrome, see [Understand Security Issues](https://developers.google.com/web/tools/chrome-devtools/security) on the Google Tools for Web Developers website.

   Other web browsers might have similar features that you can use to view the web server certificate.

1. Ensure that the SSL/TLS certificate is the one that you configured your web server to use.

**To verify SSL/TLS offload with OpenSSL s\$1client**

1. Run the following OpenSSL command to connect to your web server using HTTPS. Replace *<server name>* with the public DNS name or IP address of your web server. 

   ```
   openssl s_client -connect <server name>:443
   ```
**Tip**  
You can use a DNS service such as Amazon Route 53 to route your website's domain name (for example, https://www.example.com/) to your web server. For more information, see [Routing Traffic to an Amazon EC2 Instance](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html) in the *Amazon Route 53 Developer Guide* or in the documentation for your DNS service.

1. Ensure that the SSL/TLS certificate is the one that you configured your web server to use.

You now have a website that is secured with HTTPS. The private key for the web server is stored in an HSM in your AWS CloudHSM cluster. 

To add a load balancer, see [Add a load balancer with Elastic Load Balancing for AWS CloudHSM(optional)](third-offload-add-lb.md).

# Add a load balancer with Elastic Load Balancing for AWS CloudHSM(optional)
<a name="third-offload-add-lb"></a>

After you set up SSL/TLS offload with one web server, you can create more web servers and an Elastic Load Balancing load balancer that routes HTTPS traffic to the web servers. A load balancer can reduce the load on your individual web servers by balancing traffic across two or more servers. It can also increase the availability of your website because the load balancer monitors the health of your web servers and only routes traffic to healthy servers. If a web server fails, the load balancer automatically stops routing traffic to it.

**Topics**
+ [

## Step 1. Create a subnet for a second web server
](#ssl-offload-load-balancer-create-new-subnet)
+ [

## Step 2. Create the second web server
](#ssl-offload-load-balancer-create-web-server)
+ [

## Step 3. Create the load balancer
](#ssl-offload-load-balancer-create-load-balancer)

## Step 1. Create a subnet for a second web server
<a name="ssl-offload-load-balancer-create-new-subnet"></a>

Before you can create another web server, you need to create a new subnet in the same VPC that contains your existing web server and AWS CloudHSM cluster. 

**To create a new subnet**

1. Open the [**Subnets** section of the Amazon VPC console](https://console.aws.amazon.com/vpc/home#subnets:).

1. Choose **Create Subnet**.

1. In the **Create Subnet** dialog box, do the following:

   1. For **Name tag**, type a name for your subnet.

   1. For **VPC**, choose the AWS CloudHSM VPC that contains your existing web server and AWS CloudHSM cluster. 

   1. For **Availability Zone**, choose an Availability Zone that is different from the one that contains your existing web server. 

   1. For **IPv4 CIDR block**, type the CIDR block to use for the subnet. For example, type **10.0.10.0/24**.

   1. Choose **Yes, Create**.

1. Select the check box next to the public subnet that contains your existing web server. This is different from the public subnet that you created in the previous step. 

1. In the content pane, choose the **Route Table** tab. Then choose the link for the route table.   
![\[Choose the route table link in the Amazon VPC console.\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/console-vpc-choose-route-table.png)

1. Select the check box next to the route table.

1. Choose the **Subnet Associations** tab. Then choose **Edit**.

1. Select the check box next to the public subnet that you created earlier in this procedure. Then choose **Save**. 

## Step 2. Create the second web server
<a name="ssl-offload-load-balancer-create-web-server"></a>

Complete the following steps to create a second web server with the same configuration as your existing web server. 

**To create a second web server**

1. Open the [https://console.aws.amazon.com/ec2/v2/home#Instances:](https://console.aws.amazon.com/ec2/v2/home#Instances:) section of the Amazon EC2 console at.

1. Select the check box next to your existing web server instance.

1. Choose **Actions**, **Image**, and then **Create Image**. 

1. In the **Create Image** dialog box, do the following:

   1. For **Image name**, type a name for the image.

   1. For **Image description**, type a description for the image.

   1. Choose **Create Image**. This action reboots your existing web server.

   1. Choose the **View pending image ami-*<AMI ID>*** link.  
![\[Choose the view pending image link in the Amazon EC2 console.\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/console-ec2-choose-view-pending-image.png)

      In the **Status** column, note your image status. When your image status is **available** (this might take several minutes), go to the next step. 

1. In the navigation pane, choose **Instances**.

1. Select the check box next to your existing web server.

1. Choose **Actions** and choose **Launch More Like This**.

1. Choose **Edit AMI**.  
![\[Choose the edit AMI link in the Amazon EC2 console.\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/console-ec2-choose-edit-ami.png)

1. In the left navigation pane, choose **My AMIs**. Then clear the text in the search box. 

1. Next to your web server image, choose **Select**.

1. Choose **Yes, I want to continue with this AMI (*<image name>* - ami-*<AMI ID>*)**. 

1. Choose **Next**.

1. Select an instance type, and then choose **Next: Configure Instance Details**. 

1. For **Step 3: Configure Instance Details**, do the following:

   1. For **Network**, choose the VPC that contains your existing web server.

   1. For **Subnet**, choose the public subnet that you created for the second web server. 

   1. For **Auto-assign Public IP**, choose**Enable**.

   1. Change the remaining instance details as preferred. Then choose **Next: Add Storage**.

1. Change the storage settings as preferred. Then choose **Next: Add Tags**.

1. Add or edit tags as preferred. Then choose **Next: Configure Security Group**.

1. For **Step 6: Configure Security Group**, do the following:

   1. For **Assign a security group**, choose **Select an existing security group**. 

   1. Select the check box next to the security group named **cloudhsm-*<cluster ID>*-sg**. AWS CloudHSM created this security group on your behalf when you [created the cluster](create-cluster.md). You must choose this security group to allow the web server instance to connect to the HSMs in the cluster. 

   1. Select the check box next to the security group that allows inbound HTTPS traffic. You [created this security group previously](ssl-offload-windows.md#ssl-offload-add-security-group-windows).

   1. (Optional) Select the check box next to a security group that allows inbound SSH (for Linux) or RDP (for Windows) traffic from your network. That is, the security group must allow inbound TCP traffic on port 22 (for SSH on Linux) or port 3389 (for RDP on Windows). Otherwise, you cannot connect to your client instance. If you don't have a security group like this, you must create one and then assign it to your client instance later.

   Choose **Review and Launch**.

1. Review your instance details, and then choose **Launch**.

1. Choose whether to launch your instance with an existing key pair, create a new key pair, or launch your instance without a key pair. 
   + To use an existing key pair, do the following:

     1. Choose **Choose an existing key pair**.

     1. For **Select a key pair**, choose the key pair to use.

     1. Select the check box next to **I acknowledge that I have access to the selected private key file (*<private key file name>*.pem), and that without this file, I won't be able to log into my instance.**
   + To create a new key pair, do the following:

     1. Choose **Create a new key pair**.

     1. For **Key pair name**, type a key pair name.

     1. Choose **Download Key Pair** and save the private key file in a secure and accessible location. 
**Warning**  
You cannot download the private key file again after this point. If you do not download the private key file now, you will be unable to access the client instance. 
   + To launch your instance without a key pair, do the following:

     1. Choose **Proceed without a key pair**.

     1. Select the check box next to **I acknowledge that I will not be able to connect to this instance unless I already know the password built into this AMI.** 

   Choose **Launch Instances**.

## Step 3. Create the load balancer
<a name="ssl-offload-load-balancer-create-load-balancer"></a>

Complete the following steps to create an Elastic Load Balancing load balancer that routes HTTPS traffic to your web servers. 

**To create a load balancer**

1. Open the [ https://console.aws.amazon.com/ec2/v2/home#LoadBalancers:]( https://console.aws.amazon.com/ec2/v2/home#LoadBalancers:) section of the Amazon EC2 console.

1. Choose **Create Load Balancer**.

1. In the **Network Load Balancer** section, choose **Create**.

1. For **Step 1: Configure Load Balancer**, do the following:

   1. For **Name**, type a name for the load balancer that you are creating.

   1. In the **Listeners** section, for **Load Balancer Port**, change the value to **443**.

   1. In the **Availability Zones** section, for **VPC**, choose the VPC that contains your web servers. 

   1. In the **Availability Zones** section, choose the subnets that contain your web servers. 

   1. Choose **Next: Configure Routing**.

1. For **Step 2: Configure Routing**, do the following:

   1. For **Name**, type a name for the target group that you are creating.

   1. For **Port**, change the value to **443**.

   1. Choose **Next: Register Targets**.

1. For **Step 3: Register Targets**, do the following:

   1. In the **Instances** section, select the check boxes next to your web server instances. Then choose **Add to registered**. 

   1. Choose **Next: Review**.

1. Review your load balancer details, then choose **Create**.

1. When the load balancer has been successfully created, choose **Close**.

After you complete the preceding steps, the Amazon EC2 console shows your Elastic Load Balancing load balancer.

When your load balancer's state is active, you can verify that the load balancer is working. That is, you can verify that it's sending HTTPS traffic to your web servers with SSL/TLS offload with AWS CloudHSM. You can do this with a web browser or a tool such as [OpenSSL s\$1client](https://www.openssl.org/docs/manmaster/man1/s_client.html). 

**To verify that your load balancer is working with a web browser**

1. In the Amazon EC2 console, find the **DNS name** for the load balancer that you just created. Then select the DNS name and copy it. 

1. Use a web browser such as Mozilla Firefox or Google Chrome to connect to your load balancer using the load balancer's DNS name. Ensure that the URL in the address bar begins with https://. 
**Tip**  
You can use a DNS service such as Amazon Route 53 to route your website's domain name (for example, https://www.example.com/) to your web server. For more information, see [Routing Traffic to an Amazon EC2 Instance](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html) in the *Amazon Route 53 Developer Guide* or in the documentation for your DNS service.

1. Use your web browser to view the web server certificate. For more information, see the following: 
   + For Mozilla Firefox, see [View a Certificate](https://support.mozilla.org/en-US/kb/secure-website-certificate#w_view-a-certificate) on the Mozilla Support website.
   + For Google Chrome, see [Understand Security Issues](https://developers.google.com/web/tools/chrome-devtools/security) on the Google Tools for Web Developers website.

   Other web browsers might have similar features that you can use to view the web server certificate.

1. Ensure that the certificate is the one that you configured the web server to use.

**To verify that your load balancer is working with OpenSSL s\$1client**

1. Use the following OpenSSL command to connect to your load balancer using HTTPS. Replace *<DNS name>* with the DNS name of your load balancer. 

   ```
   openssl s_client -connect <DNS name>:443
   ```
**Tip**  
You can use a DNS service such as Amazon Route 53 to route your website's domain name (for example, https://www.example.com/) to your web server. For more information, see [Routing Traffic to an Amazon EC2 Instance](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html) in the *Amazon Route 53 Developer Guide* or in the documentation for your DNS service.

1. Ensure that the certificate is the one that you configured the web server to use.

You now have a website that is secured with HTTPS, with the web server's private key stored in an HSM in your AWS CloudHSM cluster. Your website has two web servers and a load balancer to help improve efficiency and availability. 

# Configure Windows Server as a certificate authority (CA) with AWS CloudHSM
<a name="third-ca-toplevel"></a>

AWS CloudHSM offers support to configure Windows Server as a certificate authority (CA) through Client SDK 3 and Client SDK 5. The steps to use these tools will vary depending on the version of the client SDK in which you currently have downloaded. The following sections provide information to each SDK. 

**Topics**
+ [Client SDK 5 with Windows Server CA](win-ca-overview-sdk5.md)
+ [Client SDK 3 with Windows Server CA](win-ca-overview-sdk3.md)

# Configure Windows Server as a certificate authority (CA) with Client SDK 5
<a name="win-ca-overview-sdk5"></a>

In a public key infrastructure (PKI), a certificate authority (CA) is a trusted entity that issues digital certificates. These digital certificates bind a public key to an identity (a person or organization) by means of public key cryptography and digital signatures. To operate a CA, you must maintain trust by protecting the private key that signs the certificates issued by your CA. You can store the private key in the HSM in your AWS CloudHSM cluster, and use the HSM to perform the cryptographic signing operations.

In this tutorial, you use Windows Server and AWS CloudHSM to configure a CA. You install the AWS CloudHSM client software for Windows on your Windows server, then add the Active Directory Certificate Services (AD CS) role to your Windows Server. When you configure this role, you use an AWS CloudHSM key storage provider (KSP) to create and store the CA's private key on your AWS CloudHSM cluster. The KSP is the bridge that connects your Windows server to your AWS CloudHSM cluster. In the last step, you sign a certificate signing request (CSR) with your Windows Server CA.

For more information, see the following topics:

**Topics**
+ [

## Step 1: Set up the prerequisites
](#win-ca-prerequisites-sdk5)
+ [

## Step 2: Create a Windows Server CA with AWS CloudHSM
](#win-ca-setup-sdk5)
+ [

## Step 3: Sign a certificate signing request (CSR) with your Windows Server CA with AWS CloudHSM
](#win-ca-sign-csr-sdk5)

## Step 1: Set up the prerequisites
<a name="win-ca-prerequisites-sdk5"></a>

To set up Windows Server as a certificate authority (CA) with AWS CloudHSM, you need the following:
+ An active AWS CloudHSM cluster with at least one HSM.
+ An Amazon EC2 instance running a Windows Server operating system with the AWS CloudHSM client software for Windows installed. This tutorial uses Microsoft Windows Server 2016.
+ A cryptographic user (CU) to own and manage the CA's private key on the HSM.

**To set up the prerequisites for a Windows Server CA with AWS CloudHSM**

1. Complete the steps in [Getting started](getting-started.md). When you launch the Amazon EC2 client, choose a Windows Server AMI. This tutorial uses Microsoft Windows Server 2016. When you complete these steps, you have an active cluster with at least one HSM. You also have an Amazon EC2 client instance running Windows Server with the AWS CloudHSM client software for Windows installed.

1. (Optional) Add more HSMs to your cluster. For more information, see [Adding an HSM to an AWS CloudHSM cluster](add-hsm.md).

1. Connect to your client instance. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. Create a crypto user (CU) using [Managing HSM users with CloudHSM CLI](manage-hsm-users-chsm-cli.md) or [Managing HSM users with CloudHSM Management Utility (CMU)](manage-hsm-users-cmu.md). Keep track of the CU user name and password. You will need them to complete the next step.

1. [Set the login credentials for the HSM](ksp-library-authentication.md), using the CU user name and password that you created in the previous step.

1. In step 5, if you used Windows Credentials Manager to set HSM credentials, download [https://live.sysinternals.com/psexec.exe](https://live.sysinternals.com/psexec.exe) from SysInternals to run the following command as *NT Authority\$1SYSTEM*:

   ```
   psexec.exe -s "C:\Program Files\Amazon\CloudHsm\tools\set_cloudhsm_credentials.exe" --username <USERNAME> --password <PASSWORD>
   ```

   Replace *<USERNAME>* and *<PASSWORD>* with the HSM credentials.

To create a Windows Server CA with AWS CloudHSM, go to [Create Windows Server CA](#win-ca-setup-sdk5).

## Step 2: Create a Windows Server CA with AWS CloudHSM
<a name="win-ca-setup-sdk5"></a>

To create a Windows Server CA, you add the Active Directory Certificate Services (AD CS) role to your Windows Server. When you add this role, you use an AWS CloudHSM key storage provider (KSP) to create and store the CA's private key on your AWS CloudHSM cluster.

**Note**  
When you create your Windows Server CA, you can choose to create a root CA or a subordinate CA. You typically make this decision based on the design of your public key infrastructure and the security policies of your organization. This tutorial explains how to create a root CA for simplicity.

**To add the AD CS role to your Windows Server and create the CA's private key**

1. If you haven't already done so, connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. On your Windows server, start **Server Manager**.

1. In the **Server Manager** dashboard, choose **Add roles and features**.

1. Read the **Before you begin** information, and then choose **Next**.

1. For **Installation Type**, choose **Role-based or feature-based installation**. Then choose **Next**.

1. For **Server Selection**, choose **Select a server from the server pool**. Then choose **Next**.

1. For **Server Roles**, do the following:

   1. Select **Active Directory Certificate Services**.

   1. For **Add features that are required for Active Directory Certificate Services**, choose **Add Features**.

   1. Choose **Next** to finish selecting server roles.

1. For **Features**, accept the defaults, and then choose **Next**.

1. For **AD CS**, do the following:

   1. Choose **Next**.

   1. Select **Certification Authority**, and then choose **Next**.

1. For **Confirmation**, read the confirmation information, and then choose **Install**. Do not close the window.

1. Choose the highlighted **Configure Active Directory Certificate Services on the destination server** link.

1. For **Credentials**, verify or change the credentials displayed. Then choose **Next**.

1. For **Role Services**, select **Certification Authority**. Then choose **Next**.

1. For **Setup Type**, select **Standalone CA**. Then choose **Next**.

1. For **CA Type**, select **Root CA**. Then choose **Next**.
**Note**  
You can choose to create a root CA or a subordinate CA based on the design of your public key infrastructure and the security policies of your organization. This tutorial explains how to create a root CA for simplicity.

1. For **Private Key**, select **Create a new private key**. Then choose **Next**.

1. For **Cryptography**, do the following:

   1. For **Select a cryptographic provider**, choose one of the **CloudHSM Key Storage Provider** options from the menu. These are the AWS CloudHSM key storage providers. For example, you can choose **RSA\$1CloudHSM Key Storage Provider**.

   1. For **Key length**, choose one of the key length options.

   1. For **Select the hash algorithm for signing certificates issued by this CA**, choose one of the hash algorithm options.

   Choose **Next**.

1. For **CA Name**, do the following:

   1. (Optional) Edit the common name.

   1. (Optional) Type a distinguished name suffix.

   Choose **Next**.

1. For **Validity Period**, specify a time period in years, months, weeks, or days. Then choose **Next**.

1. For **Certificate Database**, you can accept the default values, or optionally change the location for the database and the database log. Then choose **Next**.

1. For **Confirmation**, review the information about your CA; Then choose **Configure**.

1. Choose **Close**, and then choose **Close** again.

You now have a Windows Server CA with AWS CloudHSM. To learn how to sign a certificate signing request (CSR) with your CA, go to [Sign a CSR](#win-ca-sign-csr-sdk5).

## Step 3: Sign a certificate signing request (CSR) with your Windows Server CA with AWS CloudHSM
<a name="win-ca-sign-csr-sdk5"></a>

You can use your Windows Server CA with AWS CloudHSM to sign a certificate signing request (CSR). To complete these steps, you need a valid CSR. You can create a CSR in several ways, including the following:
+ Using OpenSSL
+ Using the Windows Server Internet Information Services (IIS) Manager
+ Using the certificates snap-in in the Microsoft Management Console
+ Using the **certreq** command line utility on Windows

The steps for creating a CSR are outside the scope of this tutorial. When you have a CSR, you can sign it with your Windows Server CA.

**To sign a CSR with your Windows Server CA**

1. If you haven't already done so, connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. On your Windows server, start **Server Manager**.

1. In the **Server Manager** dashboard, in the top right corner, choose **Tools**, **Certification Authority**.

1. In the **Certification Authority** window, choose your computer name.

1. From the **Action** menu, choose **All Tasks**, **Submit new request**.

1. Select your CSR file, and then choose **Open**.

1. In the **Certification Authority** window, double-click **Pending Requests**.

1. Select the pending request. Then, from the **Action** menu, choose **All Tasks**, **Issue**.

1. In the **Certification Authority** window, double-click **Issued Requests** to view the signed certificate.

1. (Optional) To export the signed certificate to a file, complete the following steps:

   1. In the **Certification Authority** window, double-click the certificate.

   1. Choose the **Details** tab, and then choose **Copy to File**.

   1. Follow the instructions in the **Certificate Export Wizard**.

You now have a Windows Server CA with AWS CloudHSM, and a valid certificate signed by the Windows Server CA.

# Configure Windows Server as a certificate authority (CA) with Client SDK 3
<a name="win-ca-overview-sdk3"></a>

In a public key infrastructure (PKI), a certificate authority (CA) is a trusted entity that issues digital certificates. These digital certificates bind a public key to an identity (a person or organization) by means of public key cryptography and digital signatures. To operate a CA, you must maintain trust by protecting the private key that signs the certificates issued by your CA. You can store the private key in the HSM in your AWS CloudHSM cluster, and use the HSM to perform the cryptographic signing operations.

In this tutorial, you use Windows Server and AWS CloudHSM to configure a CA. You install the AWS CloudHSM client software for Windows on your Windows server, then add the Active Directory Certificate Services (AD CS) role to your Windows Server. When you configure this role, you use an AWS CloudHSM key storage provider (KSP) to create and store the CA's private key on your AWS CloudHSM cluster. The KSP is the bridge that connects your Windows server to your AWS CloudHSM cluster. In the last step, you sign a certificate signing request (CSR) with your Windows Server CA.

For more information, see the following topics:

**Topics**
+ [

## Step 1: Set up the prerequisites
](#win-ca-prerequisites-sdk3)
+ [

## Step 2: Create a Windows Server CA with AWS CloudHSM
](#win-ca-setup-sdk3)
+ [

## Step 3: Sign a certificate signing request (CSR) with your Windows Server CA with AWS CloudHSM
](#win-ca-sign-csr-sdk3)

## Step 1: Set up the prerequisites
<a name="win-ca-prerequisites-sdk3"></a>

To set up Windows Server as a certificate authority (CA) with AWS CloudHSM, you need the following:
+ An active AWS CloudHSM cluster with at least one HSM.
+ An Amazon EC2 instance running a Windows Server operating system with the AWS CloudHSM client software for Windows installed. This tutorial uses Microsoft Windows Server 2016.
+ A cryptographic user (CU) to own and manage the CA's private key on the HSM.

**To set up the prerequisites for a Windows Server CA with AWS CloudHSM**

1. Complete the steps in [Getting started](getting-started.md). When you launch the Amazon EC2 client, choose a Windows Server AMI. This tutorial uses Microsoft Windows Server 2016. When you complete these steps, you have an active cluster with at least one HSM. You also have an Amazon EC2 client instance running Windows Server with the AWS CloudHSM client software for Windows installed.

1. (Optional) Add more HSMs to your cluster. For more information, see [Adding an HSM to an AWS CloudHSM cluster](add-hsm.md).

1. Connect to your client instance. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. Create a crypto user (CU) using [Managing HSM users with CloudHSM CLI](manage-hsm-users-chsm-cli.md) or [Managing HSM users with CloudHSM Management Utility (CMU)](manage-hsm-users-cmu.md). Keep track of the CU user name and password. You will need them to complete the next step.

1. [Set the login credentials for the HSM](ksp-library-prereq.md), using the CU user name and password that you created in the previous step.

1. In step 5, if you used Windows Credentials Manager to set HSM credentials, download [https://live.sysinternals.com/psexec.exe](https://live.sysinternals.com/psexec.exe) from SysInternals to run the following command as *NT Authority\$1SYSTEM*:

   ```
   	  psexec.exe -s "C:\Program Files\Amazon\CloudHsm\tools\set_cloudhsm_credentials.exe" --username <USERNAME> --password <PASSWORD>
   ```

   Replace *<USERNAME>* and *<PASSWORD>* with the HSM credentials.

To create a Windows Server CA with AWS CloudHSM, go to [Create Windows Server CA](#win-ca-setup-sdk3).

## Step 2: Create a Windows Server CA with AWS CloudHSM
<a name="win-ca-setup-sdk3"></a>

To create a Windows Server CA, you add the Active Directory Certificate Services (AD CS) role to your Windows Server. When you add this role, you use an AWS CloudHSM key storage provider (KSP) to create and store the CA's private key on your AWS CloudHSM cluster.

**Note**  
When you create your Windows Server CA, you can choose to create a root CA or a subordinate CA. You typically make this decision based on the design of your public key infrastructure and the security policies of your organization. This tutorial explains how to create a root CA for simplicity.

**To add the AD CS role to your Windows Server and create the CA's private key**

1. If you haven't already done so, connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. On your Windows server, start **Server Manager**.

1. In the **Server Manager** dashboard, choose **Add roles and features**.

1. Read the **Before you begin** information, and then choose **Next**.

1. For **Installation Type**, choose **Role-based or feature-based installation**. Then choose **Next**.

1. For **Server Selection**, choose **Select a server from the server pool**. Then choose **Next**.

1. For **Server Roles**, do the following:

   1. Select **Active Directory Certificate Services**.

   1. For **Add features that are required for Active Directory Certificate Services**, choose **Add Features**.

   1. Choose **Next** to finish selecting server roles.

1. For **Features**, accept the defaults, and then choose **Next**.

1. For **AD CS**, do the following:

   1. Choose **Next**.

   1. Select **Certification Authority**, and then choose **Next**.

1. For **Confirmation**, read the confirmation information, and then choose **Install**. Do not close the window.

1. Choose the highlighted **Configure Active Directory Certificate Services on the destination server** link.

1. For **Credentials**, verify or change the credentials displayed. Then choose **Next**.

1. For **Role Services**, select **Certification Authority**. Then choose **Next**.

1. For **Setup Type**, select **Standalone CA**. Then choose **Next**.

1. For **CA Type**, select **Root CA**. Then choose **Next**.
**Note**  
You can choose to create a root CA or a subordinate CA based on the design of your public key infrastructure and the security policies of your organization. This tutorial explains how to create a root CA for simplicity.

1. For **Private Key**, select **Create a new private key**. Then choose **Next**.

1. For **Cryptography**, do the following:

   1. For **Select a cryptographic provider**, choose one of the **Cavium Key Storage Provider** options from the menu. These are the AWS CloudHSM key storage providers. For example, you can choose **RSA\$1Cavium Key Storage Provider**.

   1. For **Key length**, choose one of the key length options.

   1. For **Select the hash algorithm for signing certificates issued by this CA**, choose one of the hash algorithm options.

   Choose **Next**.

1. For **CA Name**, do the following:

   1. (Optional) Edit the common name.

   1. (Optional) Type a distinguished name suffix.

   Choose **Next**.

1. For **Validity Period**, specify a time period in years, months, weeks, or days. Then choose **Next**.

1. For **Certificate Database**, you can accept the default values, or optionally change the location for the database and the database log. Then choose **Next**.

1. For **Confirmation**, review the information about your CA; Then choose **Configure**.

1. Choose **Close**, and then choose **Close** again.

You now have a Windows Server CA with AWS CloudHSM. To learn how to sign a certificate signing request (CSR) with your CA, go to [Sign a CSR](#win-ca-sign-csr-sdk3).

## Step 3: Sign a certificate signing request (CSR) with your Windows Server CA with AWS CloudHSM
<a name="win-ca-sign-csr-sdk3"></a>

You can use your Windows Server CA with AWS CloudHSM to sign a certificate signing request (CSR). To complete these steps, you need a valid CSR. You can create a CSR in several ways, including the following:
+ Using OpenSSL
+ Using the Windows Server Internet Information Services (IIS) Manager
+ Using the certificates snap-in in the Microsoft Management Console
+ Using the **certreq** command line utility on Windows

The steps for creating a CSR are outside the scope of this tutorial. When you have a CSR, you can sign it with your Windows Server CA.

**To sign a CSR with your Windows Server CA**

1. If you haven't already done so, connect to your Windows server. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. On your Windows server, start **Server Manager**.

1. In the **Server Manager** dashboard, in the top right corner, choose **Tools**, **Certification Authority**.

1. In the **Certification Authority** window, choose your computer name.

1. From the **Action** menu, choose **All Tasks**, **Submit new request**.

1. Select your CSR file, and then choose **Open**.

1. In the **Certification Authority** window, double-click **Pending Requests**.

1. Select the pending request. Then, from the **Action** menu, choose **All Tasks**, **Issue**.

1. In the **Certification Authority** window, double-click **Issued Requests** to view the signed certificate.

1. (Optional) To export the signed certificate to a file, complete the following steps:

   1. In the **Certification Authority** window, double-click the certificate.

   1. Choose the **Details** tab, and then choose **Copy to File**.

   1. Follow the instructions in the **Certificate Export Wizard**.

You now have a Windows Server CA with AWS CloudHSM, and a valid certificate signed by the Windows Server CA.

# Oracle database transparent data encryption (TDE) with AWS CloudHSM
<a name="oracle-tde"></a>

Transparent Data Encryption (TDE) is used to encrypt database files. Using TDE, database software encrypts data before storing it on disk. The data in the database's table columns or tablespaces are encrypted with a table key or tablespace key. Some versions of Oracle's database software offer TDE. In Oracle TDE, these keys are encrypted with a TDE master encryption key. You can achieve greater security by storing the TDE master encryption key in the HSMs in your AWS CloudHSM cluster.

![\[Store the Oracle TDE master encryption key in AWS CloudHSM.\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/tde-master-key-in-hsm.png)


In this solution, you use Oracle Database installed on an Amazon EC2 instance. Oracle Database integrates with the [AWS CloudHSM software library for PKCS \$111](pkcs11-library.md) to store the TDE master key in the HSMs in your cluster.

**Important**  
 We recommend installing Oracle Database on an Amazon EC2 instance.

Complete the following steps to accomplish Oracle TDE integration with AWS CloudHSM.

**Topics**
+ [

## Step 1. Set up the prerequisites
](#oracle-tde-prerequisites)
+ [

## Step 2: Update the Oracle database configuration
](#oracle-tde-configure-database-and-generate-master-key)
+ [

## Step 3: Generate the Oracle TDE master encryption key
](#oracle-tde-generate-master-key)

## Step 1. Set up the prerequisites
<a name="oracle-tde-prerequisites"></a>

To accomplish Oracle TDE integration with AWS CloudHSM, you need the following:
+ An active AWS CloudHSM cluster with at least one HSM.
+ An Amazon EC2 instance running the Amazon Linux operating system with the following software installed:
  + The AWS CloudHSM client and command line tools.
  + The AWS CloudHSM software library for PKCS \$111.
  + Oracle Database. AWS CloudHSM supports Oracle TDE integration. Client SDK 5.6 and higher support Oracle TDE for Oracle Database 19c. Client SDK 3 supports Oracle TDE for Oracle Database versions 11g and 12c.
+ A cryptographic user (CU) to own and manage the TDE master encryption key on the HSMs in your cluster.

Complete the following steps to set up all of the prerequisites.

**To set up the prerequisites for Oracle TDE integration with AWS CloudHSM**

1. Complete the steps in [Getting started](getting-started.md). After you do so, you'll have an active cluster with one HSM. You will also have an Amazon EC2 instance running the Amazon Linux operating system. The AWS CloudHSM client and command line tools will also be installed and configured. 

1. (Optional) Add more HSMs to your cluster. For more information, see [Adding an HSM to an AWS CloudHSM cluster](add-hsm.md). 

1. Connect to your Amazon EC2 client instance and do the following:

   1. [Install the AWS CloudHSM software library for PKCS \$111](pkcs11-library-install.md).

   1. Install Oracle Database. For more information, see the [Oracle Database documentation](https://docs.oracle.com/en/database/). Client SDK 5.6 and higher support Oracle TDE for Oracle Database 19c. Client SDK 3 supports Oracle TDE for Oracle Database versions 11g and 12c.

   1. Use the cloudhsm\$1mgmt\$1util command line tool to create a cryptographic user (CU) on your cluster. For more information about creating a CU, see [How to Manage HSM Users with CMU](create-users-cmu.md) and [HSM users](manage-hsm-users.md). 

## Step 2: Update the Oracle database configuration
<a name="oracle-tde-configure-database-and-generate-master-key"></a>

To update the Oracle Database configuration to use an HSM in your cluster as the *external security module*, complete the following steps. For information about external security modules, see [ Introduction to Transparent Data Encryption ](https://docs.oracle.com/database/122/ASOAG/introduction-to-transparent-data-encryption.htm) in the *Oracle Database Advanced Security Guide*. 

**To update the Oracle configuration**

1. Connect to your Amazon EC2 client instance. This is the instance where you installed Oracle Database.

1. Make a backup copy of the file named `sqlnet.ora`. For the location of this file, see the Oracle documentation. 

1. Use a text editor to edit the file named `sqlnet.ora`. Add the following line. If an existing line in the file begins with `encryption_wallet_location`, replace the existing line with the following one.

   ```
   encryption_wallet_location=(source=(method=hsm))
   ```

   Save the file.

1. Run the following command to create the directory where Oracle Database expects to find the library file for the AWS CloudHSM PKCS \$111 software library. 

   ```
   sudo mkdir -p /opt/oracle/extapi/64/hsm
   ```

1. Run the following command to copy the AWS CloudHSM software library for PKCS \$111 file to the directory that you created in the previous step. 

   ```
   sudo cp /opt/cloudhsm/lib/libcloudhsm_pkcs11.so /opt/oracle/extapi/64/hsm/
   ```
**Note**  
The `/opt/oracle/extapi/64/hsm` directory must contain only one library file. Remove any other files that exist in that directory. 

1. Run the following command to change the ownership of the `/opt/oracle` directory and everything inside it.

   ```
   sudo chown -R oracle:dba /opt/oracle
   ```

1. Start the Oracle Database.

## Step 3: Generate the Oracle TDE master encryption key
<a name="oracle-tde-generate-master-key"></a>

To generate the Oracle TDE master key on the HSMs in your cluster, complete the steps in the following procedure.

**To generate the master key**

1. Use the following command to open Oracle SQL\$1Plus. When prompted, type the system password that you set when you installed Oracle Database. 

   ```
   sqlplus / as sysdba
   ```
**Note**  
For Client SDK 3, you must set the `CLOUDHSM_IGNORE_CKA_MODIFIABLE_FALSE` environment variable each time you generate a master key. This variable is only needed for master key generation. For more information, see "Issue: Oracle sets the PCKS \$111 attribute `CKA_MODIFIABLE` during master key generation, but the HSM does not support it" in [Known Issues for Integrating Third-Party Applications](ki-third-party.md). 

1. Run the SQL statement that creates the master encryption key, as shown in the following examples. Use the statement that corresponds to your version of Oracle Database. Replace *<CU user name>* with the user name of the cryptographic user (CU). Replace *<password>* with the CU password. 
**Important**  
Run the following command only once. Each time the command is run, it creates a new master encryption key. 
   + For Oracle Database version 11, run the following SQL statement.

     ```
     SQL> alter system set encryption key identified by "<CU user name>:<password>";
     ```
   + For Oracle Database version 12 and version 19c, run the following SQL statement.

     ```
     SQL> administer key management set key identified by "<CU user name>:<password>";
     ```

   If the response is `System altered` or `keystore altered`, then you successfully generated and set the master key for Oracle TDE. 

1. (Optional) Run the following command to verify the status of the *Oracle wallet*.

   ```
   SQL> select * from v$encryption_wallet;
   ```

   If the wallet is not open, use one of the following commands to open it. Replace *<CU user name>* with the name of the cryptographic user (CU). Replace *<password>* with the CU password. 
   + For Oracle 11, run the following command to open the wallet.

     ```
     SQL> alter system set encryption wallet open identified by "<CU user name>:<password>";
     ```

     To manually close the wallet, run the following command.

     ```
     SQL> alter system set encryption wallet close identified by "<CU user name>:<password>";
     ```
   + For Oracle 12 and Oracle 19c, run the following command to open the wallet.

     ```
     SQL> administer key management set keystore open identified by "<CU user name>:<password>";
     ```

     To manually close the wallet, run the following command.

     ```
     SQL> administer key management set keystore close identified by "<CU user name>:<password>";
     ```

# Use Microsoft SignTool with AWS CloudHSM to sign files
<a name="third-signtool-toplevel"></a>

AWS CloudHSM offers support to use Microsoft Signtool to sign file through Client SDK 3 and Client SDK 5. The steps to use these tools will vary depending on the version of the client SDK in which you currently have downloaded. The following sections provide information to each SDK. 

**Topics**
+ [Client SDK 5 with Microsoft SignTool](signtool-sdk5.md)
+ [Client SDK 3 with Microsoft SignTool](signtool-sdk3.md)

# Use Microsoft SignTool with Client SDK 5 to sign files
<a name="signtool-sdk5"></a>

In cryptography and public key infrastructure (PKI), digital signatures are used to confirm that data has been sent by a trusted entity. Signatures also indicate that the data has not been tampered with in transit. A signature is an encrypted hash that is generated with the sender's private key. The receiver can verify the data integrity by decrypting its hash signature with the sender's public key. In turn, it is the sender's responsibility to maintain a digital certificate. The digital certificate demonstrates the sender's ownership of the private key and provides the recipient with the public key that is needed for decryption. As long as the private key is owned by the sender, the signature can be trusted. AWS CloudHSM provides secure FIPS 140-2 level 3 validated hardware for you to secure these keys with exclusive single-tenant access.

Many organizations use Microsoft SignTool, a command line tool that signs, verifies, and timestamps files to simplify the code signing process. You can use AWS CloudHSM to securely store your key pairs until they are needed by SignTool, thus creating an easily automatable workflow for signing data.

The following topics provide an overview of how to use SignTool with AWS CloudHSM.

**Topics**
+ [

## Step 1: Set up the prerequisites
](#signtool-sdk5-prereqs)
+ [

## Step 2: Create a signing certificate
](#signtool-sdk5-csr)
+ [

## Step 3: Sign a file
](#signtool-sdk5-sign)

## Step 1: Set up the prerequisites
<a name="signtool-sdk5-prereqs"></a>

To use Microsoft SignTool with AWS CloudHSM, you need the following:
+ An Amazon EC2 client instance running a Windows operating system.
+ A certificate authority (CA), either self-maintained or established by a third-party provider.
+ An active AWS CloudHSM cluster in the same virtual public cloud (VPC) as your EC2 instance. The cluster must contain at least one HSM.
+ A crypto user (CU) to own and manage keys in the AWS CloudHSM cluster.
+ An unsigned file or executable.
+ The Microsoft Windows Software Development Kit (SDK).

**To set up the prerequisites for using AWS CloudHSM with Windows SignTool**

1. Follow the instructions in the [Getting Started](getting-started.md) section of this guide to launch a Windows EC2 instance and an AWS CloudHSM cluster.

1. If you would like to host your own Windows Server CA, follow steps 1 and 2 in [Configuring Windows Server as a Certificate Authority with AWS CloudHSM](win-ca-overview-sdk5.md). Otherwise, continue to use your publicly trusted third-party CA.

1. Download and install one of the following versions of the Microsoft Windows SDK on your Windows EC2 instance:
   + [Microsoft Windows SDK 10](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
   + [Microsoft Windows SDK 8.1](https://developer.microsoft.com/en-us/windows/downloads/windows-8-1-sdk)
   + [Microsoft Windows SDK 7](https://www.microsoft.com/en-us/download/details.aspx?id=8279)

   The `SignTool` executable is part of the Windows SDK Signing Tools for Desktop Apps installation feature. You can omit the other features to be installed if you don’t need them. The default installation location is:

   ```
   C:\Program Files (x86)\Windows Kits\<SDK version>\bin\<version number>\<CPU architecture>\signtool.exe
   ```

You can now use the Microsoft Windows SDK, your AWS CloudHSM cluster, and your CA to [Create a Signing Certificate](#signtool-sdk5-csr).

## Step 2: Create a signing certificate
<a name="signtool-sdk5-csr"></a>

Now that you've downloaded the Windows SDK on to your EC2 instance, you can use it to generate a certificate signing request (CSR). The CSR is an unsigned certificate that is eventually passed to your CA for signing. In this example, we use the `certreq` executable that's included with the Windows SDK to generate the CSR.

**To generate a CSR using the `certreq` executable**

1. If you haven't already done so, connect to your Windows EC2 instance. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. Create a file called `request.inf` that contains the lines below. Replace the `Subject` information with that of your organization. For an explanation of each parameter, see [Microsoft's documentation](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1#BKMK_New).

   ```
   [Version]
   Signature= $Windows NT$
   [NewRequest]
   Subject = "C=<Country>,CN=<www.website.com>,O=<Organization>,OU=<Organizational-Unit>,L=<City>,S=<State>"
   RequestType=PKCS10
   HashAlgorithm = SHA256
   KeyAlgorithm = RSA
   KeyLength = 2048
   ProviderName = "CloudHSM Key Storage Provider"
   KeyUsage = "CERT_DIGITAL_SIGNATURE_KEY_USAGE"
   MachineKeySet = True
   Exportable = False
   ```

1. Run `certreq.exe`. For this example, we save the CSR as `request.csr`.

   ```
   certreq.exe -new request.inf request.csr
   ```

   Internally, a new key pair is generated on your AWS CloudHSM cluster, and the pair's private key is used to create the CSR.

1. Submit the CSR to your CA. If you are using a Windows Server CA, follow these steps:

   1. Enter the following command to open the CA tool:

      ```
      certsrv.msc
      ```

   1. In the new window, right-click the CA server's name. Choose **All Tasks**, and then choose **Submit new request**.

   1. Navigate to `request.csr`'s location and choose **Open**.

   1. Navigate to the **Pending Requests** folder by expanding the **Server CA** menu. Right-click on the request you just created, and under **All Tasks** choose **Issue**.

   1. Now navigate to the **Issued Certificates** folder (above the **Pending Requests** folder).

   1. Choose **Open** to view the certificate, and then choose the **Details** tab.

   1. Choose **Copy to File** to start the Certificate Export Wizard. Save the DER-encoded X.509 file to a secure location as `signedCertificate.cer`.

   1. Exit the CA tool and use the following command, which moves the certificate file to the Personal Certificate Store in Windows. It can then be used by other applications.

      ```
      certreq.exe -accept signedCertificate.cer
      ```

You can now use your imported certificate to [Sign a File ](#signtool-sdk5-sign).

## Step 3: Sign a file
<a name="signtool-sdk5-sign"></a>

You are now ready to use SignTool and your imported certificate to sign your example file. In order to do so, you need to know the certificate's SHA-1 hash, or *thumbprint*. The thumbprint is used to ensure that SignTool only uses certificates that are verified by AWS CloudHSM. In this example, we use PowerShell to get the certificate's hash. You can also use the CA's GUI or the Windows SDK's `certutil` executable. 

**To obtain a certificate's thumbprint and use it to sign a file**

1. Open PowerShell as an administrator and run the following command:

   ```
   Get-ChildItem -path cert:\LocalMachine\My
   ```

   Copy the `Thumbprint` that is returned.  
![\[The certificate's hash is returned as the thumbprint\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/signtool-hash.png)

1. Navigate to the directory within PowerShell that contains `SignTool.exe`. The default location is `C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64`.

1. Finally, sign your file by running the following command. If the command is successful, PowerShell returns a success message.

   ```
   signtool.exe sign /v /fd sha256 /sha1 <thumbprint> /sm C:\Users\Administrator\Desktop\<test>.ps1
   ```  
![\[The .ps1 file was successfully signed.\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/signtool-last-command.png)

1. (Optional) To verify the signature on the file, use the following command:

   ```
   signtool.exe verify /v /pa C:\Users\Administrator\Desktop\<test>.ps1
   ```

# Use Microsoft SignTool with Client SDK 3 to sign files
<a name="signtool-sdk3"></a>

In cryptography and public key infrastructure (PKI), digital signatures are used to confirm that data has been sent by a trusted entity. Signatures also indicate that the data has not been tampered with in transit. A signature is an encrypted hash that is generated with the sender's private key. The receiver can verify the data integrity by decrypting its hash signature with the sender's public key. In turn, it is the sender's responsibility to maintain a digital certificate. The digital certificate demonstrates the sender's ownership of the private key and provides the recipient with the public key that is needed for decryption. As long as the private key is owned by the sender, the signature can be trusted. AWS CloudHSM provides secure FIPS 140-2 level 3 validated hardware for you to secure these keys with exclusive single-tenant access.

Many organizations use Microsoft SignTool, a command line tool that signs, verifies, and timestamps files to simplify the code signing process. You can use AWS CloudHSM to securely store your key pairs until they are needed by SignTool, thus creating an easily automatable workflow for signing data.

The following topics provide an overview of how to use SignTool with AWS CloudHSM.

**Topics**
+ [

## Step 1: Set up the prerequisites
](#signtool-sdk3-prereqs)
+ [

## Step 2: Create a signing certificate
](#signtool-sdk3-csr)
+ [

## Step 3: Sign a file
](#signtool-sdk3-sign)

## Step 1: Set up the prerequisites
<a name="signtool-sdk3-prereqs"></a>

To use Microsoft SignTool with AWS CloudHSM, you need the following:
+ An Amazon EC2 client instance running a Windows operating system.
+ A certificate authority (CA), either self-maintained or established by a third-party provider.
+ An active AWS CloudHSM cluster in the same virtual public cloud (VPC) as your EC2 instance. The cluster must contain at least one HSM.
+ A crypto user (CU) to own and manage keys in the AWS CloudHSM cluster.
+ An unsigned file or executable.
+ The Microsoft Windows Software Development Kit (SDK).

**To set up the prerequisites for using AWS CloudHSM with Windows SignTool**

1. Follow the instructions in the [Getting Started](getting-started.md) section of this guide to launch a Windows EC2 instance and an AWS CloudHSM cluster.

1. If you would like to host your own Windows Server CA, follow steps 1 and 2 in [Configuring Windows Server as a Certificate Authority with AWS CloudHSM](win-ca-overview-sdk3.md). Otherwise, continue to use your publicly trusted third-party CA.

1. Download and install one of the following versions of the Microsoft Windows SDK on your Windows EC2 instance:
   + [Microsoft Windows SDK 10](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
   + [Microsoft Windows SDK 8.1](https://developer.microsoft.com/en-us/windows/downloads/windows-8-1-sdk)
   + [Microsoft Windows SDK 7](https://www.microsoft.com/en-us/download/details.aspx?id=8279)

   The `SignTool` executable is part of the Windows SDK Signing Tools for Desktop Apps installation feature. You can omit the other features to be installed if you don’t need them. The default installation location is:

   ```
   C:\Program Files (x86)\Windows Kits\<SDK version>\bin\<version number>\<CPU architecture>\signtool.exe
   ```

You can now use the Microsoft Windows SDK, your AWS CloudHSM cluster, and your CA to [Create a Signing Certificate](#signtool-sdk3-csr).

## Step 2: Create a signing certificate
<a name="signtool-sdk3-csr"></a>

Now that you've downloaded the Windows SDK on to your EC2 instance, you can use it to generate a certificate signing request (CSR). The CSR is an unsigned certificate that is eventually passed to your CA for signing. In this example, we use the `certreq` executable that's included with the Windows SDK to generate the CSR.

**To generate a CSR using the `certreq` executable**

1. If you haven't already done so, connect to your Windows EC2 instance. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. Create a file called `request.inf` that contains the lines below. Replace the `Subject` information with that of your organization. For an explanation of each parameter, see [Microsoft's documentation](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1#BKMK_New).

   ```
   [Version]
   Signature= $Windows NT$
   [NewRequest]
   Subject = "C=<Country>,CN=<www.website.com>,O=<Organization>,OU=<Organizational-Unit>,L=<City>,S=<State>"
   RequestType=PKCS10
   HashAlgorithm = SHA256
   KeyAlgorithm = RSA
   KeyLength = 2048
   ProviderName = "Cavium Key Storage Provider"
   KeyUsage = "CERT_DIGITAL_SIGNATURE_KEY_USAGE"
   MachineKeySet = True
   Exportable = False
   ```

1. Run `certreq.exe`. For this example, we save the CSR as `request.csr`.

   ```
   certreq.exe -new request.inf request.csr
   ```

   Internally, a new key pair is generated on your AWS CloudHSM cluster, and the pair's private key is used to create the CSR.

1. Submit the CSR to your CA. If you are using a Windows Server CA, follow these steps:

   1. Enter the following command to open the CA tool:

      ```
      certsrv.msc
      ```

   1. In the new window, right-click the CA server's name. Choose **All Tasks**, and then choose **Submit new request**.

   1. Navigate to `request.csr`'s location and choose **Open**.

   1. Navigate to the **Pending Requests** folder by expanding the **Server CA** menu. Right-click on the request you just created, and under **All Tasks** choose **Issue**.

   1. Now navigate to the **Issued Certificates** folder (above the **Pending Requests** folder).

   1. Choose **Open** to view the certificate, and then choose the **Details** tab.

   1. Choose **Copy to File** to start the Certificate Export Wizard. Save the DER-encoded X.509 file to a secure location as `signedCertificate.cer`.

   1. Exit the CA tool and use the following command, which moves the certificate file to the Personal Certificate Store in Windows. It can then be used by other applications.

      ```
      certreq.exe -accept signedCertificate.cer
      ```

You can now use your imported certificate to [Sign a File ](#signtool-sdk3-sign).

## Step 3: Sign a file
<a name="signtool-sdk3-sign"></a>

You are now ready to use SignTool and your imported certificate to sign your example file. In order to do so, you need to know the certificate's SHA-1 hash, or *thumbprint*. The thumbprint is used to ensure that SignTool only uses certificates that are verified by AWS CloudHSM. In this example, we use PowerShell to get the certificate's hash. You can also use the CA's GUI or the Windows SDK's `certutil` executable. 

**To obtain a certificate's thumbprint and use it to sign a file**

1. Open PowerShell as an administrator and run the following command:

   ```
   Get-ChildItem -path cert:\LocalMachine\My
   ```

   Copy the `Thumbprint` that is returned.  
![\[The certificate's hash is returned as the thumbprint\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/signtool-hash.png)

1. Navigate to the directory within PowerShell that contains `SignTool.exe`. The default location is `C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64`.

1. Finally, sign your file by running the following command. If the command is successful, PowerShell returns a success message.

   ```
   signtool.exe sign /v /fd sha256 /sha1 <thumbprint> /sm C:\Users\Administrator\Desktop\<test>.ps1
   ```  
![\[The .ps1 file was successfully signed.\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/signtool-last-command.png)

1. (Optional) To verify the signature on the file, use the following command:

   ```
   signtool.exe verify /v /pa C:\Users\Administrator\Desktop\<test>.ps1
   ```

# Java Keytool and Jarsigner integration with AWS CloudHSM
<a name="third_java-sdk_integration"></a>

AWS CloudHSM offers integration with the Java Keytool and Jarsigner utilities through Client SDK 3 and Client SDK 5. The steps to use these tools will vary depending on the version of the client SDK in which you currently have downloaded. The following sections provide information to each SDK. 

**Topics**
+ [Client SDK 5 with Java Keytool and Jarsigner](keystore-third-party-tools_5.md)
+ [Client SDK 3 with Java Keytool and Jarsigner](keystore-third-party-tools.md)

# Use Client SDK 5 to integrate AWS CloudHSM with Java Keytool and Jarsigner
<a name="keystore-third-party-tools_5"></a>

AWS CloudHSM key store is a special-purpose JCE key store that utilizes certificates associated with keys on your hardware security module (HSM) through third-party tools such as `keytool` and `jarsigner`. AWS CloudHSM does not store certificates on the HSM, as certificates are public, non-confidential data. The AWS CloudHSM key store stores the certificates in a local file and maps the certificates to corresponding keys on your HSM. 

When you use the AWS CloudHSM key store to generate new keys, no entries are generated in the local key store file – the keys are created on the HSM. Similarly, when you use the AWS CloudHSM key store to search for keys, the search is passed on to the HSM. When you store certificates in the AWS CloudHSM key store, the provider verifies that a key pair with the corresponding alias exists on the HSM, and then associates the certificate provided with the corresponding key pair. 

**Topics**
+ [Prerequisites](keystore-prerequisites_5.md)
+ [Use key store with keytool](using_keystore_with_keytool_5.md)
+ [Use key store with Jarsigner](using_keystore_jarsigner_5.md)
+ [Known issues](known-issues-keytool-jarsigner_5.md)

# Prerequisites for integrating AWS CloudHSM with Java Keytool and Jarsigner using Client SDK 5
<a name="keystore-prerequisites_5"></a>

To use the AWS CloudHSM key store, you must first initialize and configure the AWS CloudHSM JCE SDK. Use the following steps to do so. 

## Step 1: Install the JCE
<a name="prereq-step-one_5"></a>

To install the JCE, including the AWS CloudHSM client prerequisites, follow the steps for [installing the Java library](java-library-install_5.md). 

## Step 2: Add HSM login credentials to environment variables
<a name="prereq-step-two_5"></a>

Set up environment variables to contain your HSM login credentials. 

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

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

```
$ export HSM_PASSWORD=<HSM password>
```

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

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

```
PS C:\> $Env:HSM_PASSWORD=<HSM password>
```

------

**Note**  
The AWS CloudHSM JCE offers various login options. To use the AWS CloudHSM key store with third-party applications, you must use implicit login with environment variables. If you want to use explicit login through application code, you must build your own application using the AWS CloudHSM key store. For additional information, see the article on [Using AWS CloudHSM Key Store](alternative-keystore_5.md). 

## Step 3: Registering the JCE provider
<a name="prereq-step-three_5"></a>

To register the JCE provider in the Java CloudProvider configuration, follow these steps: 

1. Open the `java.security` configuration file in your Java installation for editing.

1. In the `java.security` configuration file, add `com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider` as the last provider. For example, if there are nine providers in the `java.security` file, add the following provider as the last provider in the section:

   `security.provider.10=com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider`

**Note**  
Adding the AWS CloudHSM provider as a higher priority may negatively impact your system's performance because the AWS CloudHSM provider will be prioritized for operations that may be safely offloaded to software. As a best practice, **always** specify the provider you wish to use for an operation, whether it is the AWS CloudHSM or a software-based provider.

**Note**  
Specifying `-providerName`, `-providerclass`, and `-providerpath` command line options when generating keys using **keytool** with the AWS CloudHSM key store may cause errors.

# Use AWS CloudHSM key store with keytool using Client SDK 5
<a name="using_keystore_with_keytool_5"></a>

 [ Keytool](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html) is a popular command line utility for common key and certificate tasks. A complete tutorial on keytool is out of scope for AWS CloudHSM documentation. This article explains the specific parameters you should use with various keytool functions when utilizing AWS CloudHSM as the root of trust through the AWS CloudHSM key store.

When using keytool with the AWS CloudHSM key store, specify the following arguments to any keytool command:

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

```
-storetype CLOUDHSM -J-classpath< '-J/opt/cloudhsm/java/*'>
```

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

```
-storetype CLOUDHSM -J-classpath<'-J"C:\Program Files\Amazon\CloudHSM\java\*"'>
```

------

If you want to create a new key store file using AWS CloudHSM key store, see [Use the AWS CloudHSM KeyStore for AWS CloudHSM Client SDK 3](alternative-keystore.md#using_cloudhsm_keystore). To use an existing key store, specify its name (including path) using the –keystore argument to keytool. If you specify a non-existent key store file in a keytool command, the AWS CloudHSM key store creates a new key store file.

# Create new AWS CloudHSM keys with keytool
<a name="create_key_keytool_5"></a>

You can use keytool to generate RSA, AES, and DESede type of key supported by the AWS CloudHSM JCE SDK.

**Important**  
A key generated through keytool is generated in software, and then imported into AWS CloudHSM as an extractable, persistent key.

We strongly recommend generating non-exportable keys outside of keytool, and then importing corresponding certificates to the key store. If you use extractable RSA or EC keys through keytool and Jarsigner, the providers export keys from the AWS CloudHSM and then use the key locally for signing operations.

If you have multiple client instances connected to your AWS CloudHSM cluster, be aware that importing a certificate on one client instance’s key store won't automatically make the certificates available on other client instances. To register the key and associated certificates on each client instance you need to run a Java application as described in [Generate an AWS CloudHSM CSR using keytool](generate_csr_using_keytool_5.md). Alternatively, you can make the necessary changes on one client and copy the resulting key store file to every other client instance.

**Example 1: **To generate a symmetric AES-256 key and save it in a key store file named, "example\$1keystore.store", in the working directory. Replace *<secret label>* with a unique label.

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

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

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

```
PS C:\> keytool -genseckey -alias <secret label> -keyalg aes `
	-keysize 256 -keystore example_keystore.store `
	-storetype CloudHSM -J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'
```

------

**Example 2: **To generate an RSA 2048 key pair and save it in a key store file named, "example\$1keystore.store" in the working directory. Replace *<RSA key pair label>* with a unique label.

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

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

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

```
PS C:\> keytool -genkeypair -alias <RSA key pair label> `
	-keyalg rsa -keysize 2048 `
	-sigalg sha512withrsa `
	-keystore example_keystore.store `
	-storetype CLOUDHSM `
	-J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'
```

------

You can find a list of [supported signature algorithms](java-lib-supported_5.md#java-sign-verify_5) in the Java library.

# Delete an AWS CloudHSM key using keytool
<a name="delete_key_using_keytool_5"></a>

The AWS CloudHSM key store doesn't support deleting keys. You can delete keys using the destroy method of the [Destroyable interface](https://devdocs.io/openjdk%7E8/javax/security/auth/destroyable#destroy--).

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

# Generate an AWS CloudHSM CSR using keytool
<a name="generate_csr_using_keytool_5"></a>

You receive the greatest flexibility in generating a certificate signing request (CSR) if you use the [OpenSSL Dynamic Engine for AWS CloudHSM Client SDK 5](openssl-library.md). The following command uses keytool to generate a CSR for a key pair with the alias, `example-key-pair`.

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

```
$ keytool -certreq -alias <key pair label> \
	-file my_csr.csr \
	-keystore example_keystore.store \
	-storetype CLOUDHSM \
	-J-classpath '-J/opt/cloudhsm/java/*'
```

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

```
PS C:\> keytool -certreq -alias <key pair label> `
	-file my_csr.csr `
	-keystore example_keystore.store `
	-storetype CLOUDHSM `
	-J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'
```

------

**Note**  
To use a key pair from keytool, that key pair must have an entry in the specified key store file. If you want to use a key pair that was generated outside of keytool, you must import the key and certificate metadata into the key store. For instructions on importing the keystore data see [Use keytool to import intermediate and root certificates into AWS CloudHSM key store](import_cert_using_keytool_5.md).

# Use keytool to import intermediate and root certificates into AWS CloudHSM key store
<a name="import_cert_using_keytool_5"></a>

To import a CA certificate in AWS CloudHSM, you must enable verification of a full certificate chain on a newly imported certificate. The following command shows an example. 

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

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

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

```
PS C:\> keytool -import -trustcacerts -alias rootCAcert `
	-file rootCAcert.cert -keystore example_keystore.store `
	-storetype CLOUDHSM `
	-J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'
```

------

If you connect multiple client instances to your AWS CloudHSM cluster, importing a certificate on one client instance’s key store won't automatically make the certificate available on other client instances. You must import the certificate on each client instance.

# Use keytool to delete certificates from AWS CloudHSM key store
<a name="delete_cert_using_keytool_5"></a>

The following command shows an example of how to delete a AWS CloudHSM certificate from a Java keytool key store. 

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

```
$ keytool -delete -alias mydomain \
	-keystore example_keystore.store \
	-storetype CLOUDHSM \
	-J-classpath '-J/opt/cloudhsm/java/*'
```

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

```
PS C:\> keytool -delete -alias mydomain `
	-keystore example_keystore.store `
	-storetype CLOUDHSM `
	-J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'
```

------

If you connect multiple client instances to your AWS CloudHSM cluster, deleting a certificate on one client instance’s key store won't automatically remove the certificate from other client instances. You must delete the certificate on each client instance.

# Import a working certificate into AWS CloudHSM key store using keytool
<a name="import_working_cert_using_keytool_5"></a>

Once a certificate signing request (CSR) is signed, you can import it into the AWS CloudHSM key store and associate it with the appropriate key pair. The following command provides an example. 

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

```
$ keytool -importcert -noprompt -alias <key pair label> \
	-file my_certificate.crt \
	-keystore example_keystore.store \
	-storetype CLOUDHSM \
	-J-classpath '-J/opt/cloudhsm/java/*'
```

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

```
PS C:\> keytool -importcert -noprompt -alias <key pair label> `
	-file my_certificate.crt `
	-keystore example_keystore.store `
	-storetype CLOUDHSM `
	-J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'
```

------

The alias should be a key pair with an associated certificate in the key store. If the key is generated outside of keytool, or is generated on a different client instance, you must first import the key and certificate metadata into the key store. 

The certificate chain must be verifiable. If you can't verify the certificate, you might need to import the signing (certificate authority) certificate into the key store so the chain can be verified.

# Export a certificate from AWS CloudHSM using keytool
<a name="export_cert_using_keytool_5"></a>

The following example generates a certificate in binary X.509 format. To export a human readable certificate from AWS CloudHSM, add `-rfc` to the `-exportcert` command. 

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

```
$ keytool -exportcert -alias <key pair label> \
	-file my_exported_certificate.crt \
	-keystore example_keystore.store \
	-storetype CLOUDHSM \
	-J-classpath '-J/opt/cloudhsm/java/*'
```

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

```
PS C:\> keytool -exportcert -alias <key pair label> `
	-file my_exported_certificate.crt `
	-keystore example_keystore.store `
	-storetype CLOUDHSM `
	-J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'
```

------

# Use AWS CloudHSM key store with Jarsigner using Client SDK 5
<a name="using_keystore_jarsigner_5"></a>

Jarsigner is a popular command line utility for signing JAR files using a key securely stored on a hardware security module (HSM). A complete tutorial on Jarsigner is out of scope for the AWS CloudHSM documentation. This section explains the Jarsigner parameters you should use to sign and verify signatures with AWS CloudHSM as the root of trust through the AWS CloudHSM key store. 

# Set up AWS CloudHSM keys and certificates with Jarsigner
<a name="jarsigner_set_up_certificates_5"></a>

Before you can sign AWS CloudHSM JAR files with Jarsigner, make sure you have set up or completed the following steps: 

1. Follow the guidance in the [AWS CloudHSM key store prerequisites ](keystore-prerequisites_5.md).

1. Set up your signing keys and the associated certificates and certificate chain which should be stored in the AWS CloudHSM key store of the current server or client instance. Create the keys on the AWS CloudHSM and then import associated metadata into your AWS CloudHSM key store. If you want to use keytool to set up the keys and certificates, see [Create new AWS CloudHSM keys with keytool](create_key_keytool_5.md). If you use multiple client instances to sign your JARs, create the key and import the certificate chain. Then copy the resulting key store file to each client instance. If you frequently generate new keys, you may find it easier to individually import certificates to each client instance.

1. The entire certificate chain should be verifiable. For the certificate chain to be verifiable, you may need to add the CA certificate and intermediate certificates to the AWS CloudHSM key store. See the code snippet in [Sign a JAR file using AWS CloudHSM and Jarsigner](jarsigner_sign_jar_using_hsm_jarsigner_5.md) for instruction on using Java code to verify the certificate chain. If you prefer, you can use keytool to import certificates. For instructions on using keytool, see [Use keytool to import intermediate and root certificates into AWS CloudHSM key store](import_cert_using_keytool_5.md). 

# Sign a JAR file using AWS CloudHSM and Jarsigner
<a name="jarsigner_sign_jar_using_hsm_jarsigner_5"></a>

Use the following command to sign a JAR file using AWS CloudHSM and Jarsigner: 

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

For OpenJDK 8

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

For OpenJDK 11, OpenJDK 17, and OpenJDK 21

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

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

For OpenJDK8

```
jarsigner -keystore example_keystore.store `
	-signedjar signthisclass_signed.jar `
	-sigalg sha512withrsa `
	-storetype CloudHSM `
	-J-classpath '-JC:\Program Files\Amazon\CloudHSM\java\*;C:\Program Files\Java\jdk1.8.0_331\lib\tools.jar' `
	 "-J-Djava.library.path='C:\Program Files\Amazon\CloudHSM\lib\'" `
	signthisclass.jar <key pair label>
```

For OpenJDK 11, OpenJDK 17, and OpenJDK 21

```
jarsigner -keystore example_keystore.store `
	-signedjar signthisclass_signed.jar `
	-sigalg sha512withrsa `
	-storetype CloudHSM `
	-J-classpath '-JC:\Program Files\Amazon\CloudHSM\java\*'`
	 "-J-Djava.library.path='C:\Program Files\Amazon\CloudHSM\lib\'" `
	signthisclass.jar <key pair label>
```

------

Use the following command to verify a signed JAR: 

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

For OpenJDK8

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

For OpenJDK 11, OpenJDK 17, and OpenJDK 21

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

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

For OpenJDK 8

```
jarsigner -verify `
	-keystore example_keystore.store `
	-sigalg sha512withrsa `
	-storetype CloudHSM `
	-J-classpath '-JC:\Program Files\Amazon\CloudHSM\java\*;C:\Program Files\Java\jdk1.8.0_331\lib\tools.jar' `
	"-J-Djava.library.path='C:\Program Files\Amazon\CloudHSM\lib\'" `
	signthisclass_signed.jar <key pair label>
```

For OpenJDK 11, OpenJDK 17, and OpenJDK 21

```
jarsigner -verify `
	-keystore example_keystore.store `
	-sigalg sha512withrsa `
	-storetype CloudHSM `
	-J-classpath '-JC:\Program Files\Amazon\CloudHSM\java\*`
	"-J-Djava.library.path='C:\Program Files\Amazon\CloudHSM\lib\'" `
	signthisclass_signed.jar <key pair label>
```

------

# Known issues for AWS CloudHSM integration Java Keytool and Jarsigner using Client SDK 5
<a name="known-issues-keytool-jarsigner_5"></a>

The following list provides the current list of known issues for integrations with AWS CloudHSM and Java Keytool and Jarsigner using Client SDK 5. 

1. We do not support EC keys with Keytool and Jarsigner.

# Use Client SDK 3 to integrate AWS CloudHSM with Java Keytool and Jarsigner
<a name="keystore-third-party-tools"></a>

AWS CloudHSM key store is a special-purpose JCE key store that utilizes certificates associated with keys on your hardware security module (HSM) through third-party tools such as `keytool` and `jarsigner`. AWS CloudHSM does not store certificates on the HSM, as certificates are public, non-confidential data. The AWS CloudHSM key store stores the certificates in a local file and maps the certificates to corresponding keys on your HSM. 

When you use the AWS CloudHSM key store to generate new keys, no entries are generated in the local key store file – the keys are created on the HSM. Similarly, when you use the AWS CloudHSM key store to search for keys, the search is passed on to the HSM. When you store certificates in the AWS CloudHSM key store, the provider verifies that a key pair with the corresponding alias exists on the HSM, and then associates the certificate provided with the corresponding key pair. 

**Topics**
+ [Prerequisites](keystore-prerequisites.md)
+ [Use key store with keytool](using_keystore_with_keytool.md)
+ [Use key store with jarsigner](using_keystore_jarsigner.md)
+ [Known issues](known-issues-keytool-jarsigner.md)
+ [Register pre-existing keys with key store](register-pre-existing-keys-with-keystore.md)

# Prerequisites for integrating AWS CloudHSM with Java Keytool and Jarsigner using Client SDK 3
<a name="keystore-prerequisites"></a>

To use the AWS CloudHSM key store, you must first initialize and configure the AWS CloudHSM JCE SDK. Use the following steps to do so. 

## Step 1: Install the JCE
<a name="prereq-step-one"></a>

To install the JCE, including the AWS CloudHSM client prerequisites, follow the steps for [installing the Java library](java-library-install.md). 

## Step 2: Add HSM login credentials to environment variables
<a name="prereq-step-two"></a>

Set up environment variables to contain your HSM login credentials. 

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

**Note**  
The CloudHSM JCE offers various login options. To use the AWS CloudHSM key store with third-party applications, you must use implicit login with environment variables. If you want to use explicit login through application code, you must build your own application using the AWS CloudHSM key store. For additional information, see the article on [Using AWS CloudHSM Key Store](alternative-keystore.md). 

## Step 3: Register the JCE provider
<a name="prereq-step-three"></a>

To register the JCE provider, in the Java CloudProvider configuration. 

1. Open the java.security configuration file in your Java installation, for editing.

1. In the java.security configuration file, add `com.cavium.provider.CaviumProvider` as the last provider. For example, if there are nine providers in the java.security file, add the following provider as the last provider in the section. Adding the Cavium provider as a higher priority may negatively impact your system's performance.

   `security.provider.10=com.cavium.provider.CaviumProvider`
**Note**  
Power users may be accustomed to specifying `-providerName`, `-providerclass`, and `-providerpath` command line options when using keytool, instead of updating the security configuration file. If you attempt to specify command line options when generating keys with AWS CloudHSM key store, it will cause errors. 

# Use AWS CloudHSM key store with keytool using Client SDK 3
<a name="using_keystore_with_keytool"></a>

[ Keytool](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html) is a popular command line utility for common key and certificate tasks on Linux systems. A complete tutorial on keytool is out of scope for AWS CloudHSM documentation. This article explains the specific parameters you should use with various keytool functions when utilizing AWS CloudHSM as the root of trust through the AWS CloudHSM key store.

When using keytool with the AWS CloudHSM key store, specify the following arguments to any keytool command:

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

If you want to create a new key store file using AWS CloudHSM key store, see [Use the AWS CloudHSM KeyStore for AWS CloudHSM Client SDK 3](alternative-keystore.md#using_cloudhsm_keystore). To use an existing key store, specify its name (including path) using the –keystore argument to keytool. If you specify a non-existent key store file in a keytool command, the AWS CloudHSM key store creates a new key store file.

# Create new AWS CloudHSM keys with keytool
<a name="create_key_keytool"></a>

You can use keytool to generate any type of key supported by the AWS CloudHSM JCE SDK. See a full list of keys and lengths in the [ Supported Keys](java-lib-supported.md#java-keys) article in the Java Library.

**Important**  
A key generated through keytool is generated in software, and then imported into AWS CloudHSM as an extractable, persistent key.

Instructions for creating non-extractable keys directly on the hardware security module (HSM), and then using them with keytool or Jarsigner, are shown in the code sample in [Registering Pre-existing Keys with AWS CloudHSM Key Store](register-pre-existing-keys-with-keystore.md). We strongly recommend generating non-exportable keys outside of keytool, and then importing corresponding certificates to the key store. If you use extractable RSA or EC keys through keytool and jarsigner, the providers export keys from the AWS CloudHSM and then use the key locally for signing operations.

If you have multiple client instances connected to your CloudHSM cluster, be aware that importing a certificate on one client instance’s key store won't automatically make the certificates available on other client instances. To register the key and associated certificates on each client instance you need to run a Java application as described in [Generate a CSR using Keytool](generate_csr_using_keytool.md). Alternatively, you can make the necessary changes on one client and copy the resulting key store file to every other client instance.

**Example 1: **To generate a symmetric AES-256 key and save it in a key store file named, "example\$1keystore.store", in the working directory. Replace *<secret label>* with a unique label.

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

**Example 2: **To generate an RSA 2048 key pair and save it in a key store file named, "example\$1keystore.store" in the working directory. Replace *<RSA key pair label>* with a unique label.

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

**Example 3: **To generate a p256 ED key and save it in a key store file named, "example\$1keystore.store" in the working directory. Replace *<ec key pair label>* with a unique label.

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

You can find a list of [supported signature algorithms](java-lib-supported.md#java-sign-verify) in the Java library.

# Delete an AWS CloudHSM key using keytool
<a name="delete_key_using_keytool"></a>

The AWS CloudHSM key store doesn't support deleting keys. To delete key, you must use the `deleteKey` function of AWS CloudHSM's command line tool, [Delete an AWS CloudHSM key using KMU](key_mgmt_util-deleteKey.md).

# Generate an AWS CloudHSM CSR using keytool
<a name="generate_csr_using_keytool"></a>

You receive the greatest flexibility in generating a certificate signing request (CSR) if you use the [OpenSSL Dynamic Engine for AWS CloudHSM Client SDK 5](openssl-library.md). The following command uses keytool to generate a CSR for a key pair with the alias, `example-key-pair`.

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

**Note**  
To use a key pair from keytool, that key pair must have an entry in the specified key store file. If you want to use a key pair that was generated outside of keytool, you must import the key and certificate metadata into the key store. For instructions on importing the keystore data see [Importing Intermediate and root certificates into AWS CloudHSM Key Store using Keytool](import_cert_using_keytool.md).

# Use keytool to import intermediate and root certificates into AWS CloudHSM key store
<a name="import_cert_using_keytool"></a>

To import a CA certificate into AWS CloudHSM, you must enable verification of a full certificate chain on a newly imported certificate. The following command shows an example. 

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

If you connect multiple client instances to your AWS CloudHSM cluster, importing a certificate on one client instance’s key store won't automatically make the certificate available on other client instances. You must import the certificate on each client instance.

# Use keytool to delete certificates from AWS CloudHSM key store
<a name="delete_cert_using_keytool"></a>

The following command shows an example of how to delete an AWS CloudHSM certificate from a Java keytool key store. 

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

If you connect multiple client instances to your AWS CloudHSM cluster, deleting a certificate on one client instance’s key store won't automatically remove the certificate from other client instances. You must delete the certificate on each client instance.

# Import a working certificate into AWS CloudHSM key store using keytool
<a name="import_working_cert_using_keytool"></a>

Once a certificate signing request (CSR) is signed, you can import it into the AWS CloudHSM key store and associate it with the appropriate key pair. The following command provides an example. 

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

The alias should be a key pair with an associated certificate in the key store. If the key is generated outside of keytool, or is generated on a different client instance, you must first import the key and certificate metadata into the key store. For instructions on importing the certificate metadata, see the code sample in [Registering Pre-existing Keys with AWS CloudHSM Key Store](register-pre-existing-keys-with-keystore.md). 

The certificate chain must be verifiable. If you can't verify the certificate, you might need to import the signing (certificate authority) certificate into the key store so the chain can be verified.

# Export a certificate from AWS CloudHSM using keytool
<a name="export_cert_using_keytool"></a>

The following example generates a certificate in binary X.509 format. To export a human readable certificate from AWS CloudHSM, add `-rfc` to the `-exportcert` command. 

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

# Use AWS CloudHSM key store with Jarsigner using Client SDK 3
<a name="using_keystore_jarsigner"></a>

Jarsigner is a popular command line utility for signing JAR files using a key securely stored on a hardware security module (HSM). A complete tutorial on Jarsigner is out of scope for the AWS CloudHSM documentation. This section explains the Jarsigner parameters you should use to sign and verify signatures with AWS CloudHSM as the root of trust through the AWS CloudHSM key store. 

# Set up AWS CloudHSM keys and certificates with Jarsigner
<a name="jarsigner_set_up_certificates"></a>

Before you can sign AWS CloudHSM JAR files with Jarsigner, make sure you have set up or completed the following steps: 

1. Follow the guidance in the [AWS CloudHSM Key store prerequisites ](keystore-prerequisites.md).

1. Set up your signing keys and the associated certificates and certificate chain which should be stored in the AWS CloudHSM key store of the current server or client instance. Create the keys on the AWS CloudHSM and then import associated metadata into your AWS CloudHSM key store. Use the code sample in [Registering Pre-existing Keys with AWS CloudHSM Key Store](register-pre-existing-keys-with-keystore.md) to import metadata into the key store. If you want to use keytool to set up the keys and certificates, see [Create new AWS CloudHSM keys with keytool](create_key_keytool.md). If you use multiple client instances to sign your JARs, create the key and import the certificate chain. Then copy the resulting key store file to each client instance. If you frequently generate new keys, you may find it easier to individually import certificates to each client instance.

1. The entire certificate chain should be verifiable. For the certificate chain to be verifiable, you may need to add the CA certificate and intermediate certificates to the AWS CloudHSM key store. See the code snippet in [Sign a JAR file using AWS CloudHSM and Jarsigner](jarsigner_sign_jar_using_hsm_jarsigner.md) for instruction on using Java code to verify the certificate chain. If you prefer, you can use keytool to import certificates. For instructions on using keytool, see [Using Keytool to import intermediate and root certificates into AWS CloudHSM Key Store](import_cert_using_keytool.md). 

# Sign a JAR file using AWS CloudHSM and Jarsigner
<a name="jarsigner_sign_jar_using_hsm_jarsigner"></a>

Use the following command to sign a JAR file using AWS CloudHSM and jarsigner: 

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

Use the following command to verify a signed JAR: 

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

# Known issues for AWS CloudHSM integration Java Keytool and Jarsigner using Client SDK 3
<a name="known-issues-keytool-jarsigner"></a>

The following list provides the current list of known issues for integrations with AWS CloudHSM and Java Keytool and Jarsigner using Client SDK 3. 
+ When generating keys using keytool, the first provider in provider configuration cannot be CaviumProvider. 
+ When generating keys using keytool, the first (supported) provider in the security configuration file is used to generate the key. This is generally a software provider. The generated key is then given an alias and imported into the AWS CloudHSM HSM as a persistent (token) key during the key addition process. 
+  When using keytool with AWS CloudHSM key store, do not specify `-providerName`, `-providerclass`, or `-providerpath` options on the command line. Specify these options in the security provider file as described in the [Key store prerequisites](keystore-prerequisites.md). 
+ When using non-extractable EC keys through keytool and Jarsigner, the SunEC provider needs to be removed/disabled from the list of providers in the java.security file. If you use extractable EC keys through keytool and Jarsigner, the providers export key bits from the AWS CloudHSM HSM and use the key locally for signing operations. We do not recommend you use exportable keys with keytool or Jarsigner.

# Register pre-existing keys with AWS CloudHSM key store
<a name="register-pre-existing-keys-with-keystore"></a>

For maximum security and flexibility in attributes and labeling, we recommend you generate your AWS CloudHSM signing keys using [key\$1mgmt\$1util](generate-keys.md). You can also use a Java application to generate the key in AWS CloudHSM.

The following section provides a code sample that demonstrates how to generate a new key pair on the HSM and register it using existing keys imported to the AWS CloudHSM key store. The imported keys are available for use with third-party tools such as keytool and Jarsigner. 

To use a pre-existing key, modify the code sample to look up a key by label instead of generating a new key. Sample code for looking up a key by label is available in the [KeyUtilitiesRunner.java sample](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/master/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java) on GitHub. 

**Important**  
Registering a key stored on AWS CloudHSM with a local key store does not export the key. When the key is registered, the key store registers the key's alias (or label) and correlates locally store certificate objects with a key pair on the AWS CloudHSM. As long as the key pair is created as non-exportable, the key bits won't leave the HSM. 

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

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

import javax.crypto.KeyGenerator;

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

import java.math.BigInteger;

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

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

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

public class KeyStoreExampleRunner {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        keyPairGen.initialize(spec);

        return keyPairGen.generateKeyPair();
    }

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

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

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

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

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

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

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

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

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

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

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

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

}
```

# Use Microsoft Manifest Generation and Editing Tool (Mage.exe) with AWS CloudHSM to sign files
<a name="third-magetool"></a>

**Note**  
AWS CloudHSM supports only the 64-bit Mage tool included in the Windows SDK for .NET Framework 4.8.1 and later.

The following topics provide an overview of how to use [ Mage.exe ](https://learn.microsoft.com/en-us/dotnet/framework/tools/mage-exe-manifest-generation-and-editing-tool) with AWS CloudHSM.

**Topics**
+ [

## Step 1: Set up the prerequisites
](#magetool-prereqs)
+ [

## Step 2: Create a signing certificate
](#magetool-csr)
+ [

## Step 3: Sign a file
](#magetool-sign)

## Step 1: Set up the prerequisites
<a name="magetool-prereqs"></a>

To use Microsoft Mage.exe with AWS CloudHSM, you need the following:
+ An Amazon EC2 instance running a Windows operating system
+ A certificate authority (CA), either self-maintained or from a third-party provider
+ An active AWS CloudHSM cluster in the same virtual private cloud (VPC) as your EC2 instance, with at least one HSM
+ A crypto user (CU) to own and manage keys in the AWS CloudHSM cluster
+ An unsigned file or executable
+ The Microsoft Windows Software Development Kit (SDK)

**To set up the prerequisites for using AWS CloudHSM with Mage.exe**

1. Launch a Windows EC2 instance and an AWS CloudHSM cluster by following the instructions in the [Getting Started](getting-started.md) section of this guide.

1. If you want to host your own Windows Server CA, complete steps 1 and 2 in [Configuring Windows Server as a Certificate Authority with AWS CloudHSM](win-ca-overview-sdk5.md). Otherwise, use your publicly trusted third-party CA.

1. Download and install Microsoft Windows SDK for .NET Framework 4.8.1 or later on your Windows EC2 instance:
   + [Microsoft Windows SDK 10](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)

   The `mage.exe` executable is part of the Windows SDK Tools. The default installation location is:

   ```
   C:\Program Files (x86)\Windows Kits\<SDK version>\bin\<version number>\x64\Mage.exe
   ```

After completing these steps, you can use the Microsoft Windows SDK, your AWS CloudHSM cluster, and your CA to [create a signing certificate](#magetool-csr).

## Step 2: Create a signing certificate
<a name="magetool-csr"></a>

Now that you've installed the Windows SDK on your EC2 instance, you can use it to generate a certificate signing request (CSR). The CSR is an unsigned certificate that you submit to your CA for signing. In this example, we use the `certreq` executable included with the Windows SDK to generate the CSR.

**To generate a CSR using the certreq executable**

1. Connect to your Windows EC2 instance. For more information, see [Connect to Your Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html#ec2-connect-to-instance-windows) in the *Amazon EC2 User Guide*.

1. Create a file named `request.inf` with the following content. Replace the `Subject` information with your organization's details:

   ```
   [Version]
   Signature= $Windows NT$
   [NewRequest]
   Subject = "C=<Country>,CN=<www.website.com>,O=<Organization>,OU=<Organizational-Unit>,L=<City>,S=<State>"
   RequestType=PKCS10
   HashAlgorithm = SHA256
   KeyAlgorithm = RSA
   KeyLength = 2048
   ProviderName = "CloudHSM Key Storage Provider"
   KeyUsage = "CERT_DIGITAL_SIGNATURE_KEY_USAGE"
   MachineKeySet = True
   Exportable = False
   ```

   For an explanation of each parameter, see [Microsoft's documentation](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1#BKMK_New).

1. Run `certreq.exe` to generate the CSR:

   ```
   certreq.exe -new request.inf request.csr
   ```

   This command generates a new key pair on your AWS CloudHSM cluster and uses the private key to create the CSR.

1. Submit the CSR to your CA. If you're using a Windows Server CA, follow these steps:

   1. Open the CA tool:

      ```
      certsrv.msc
      ```

   1. In the new window, right-click the CA server's name. Choose **All Tasks**, and then choose **Submit new request**.

   1. Navigate to the location of `request.csr` and choose **Open**.

   1. Expand the **Server CA** menu and navigate to the **Pending Requests** folder. Right-click the request you just created, choose **All Tasks**, and then choose **Issue**.

   1. Navigate to the **Issued Certificates** folder.

   1. Choose **Open** to view the certificate, and then choose the **Details** tab.

   1. Choose **Copy to File** to start the Certificate Export Wizard. Save the DER-encoded X.509 file to a secure location as `signedCertificate.cer`.

   1. Exit the CA tool and run the following command to move the certificate file to the Personal Certificate Store in Windows:

      ```
      certreq.exe -accept signedCertificate.cer
      ```

You can now use your imported certificate to [sign a file](#magetool-sign).

## Step 3: Sign a file
<a name="magetool-sign"></a>

Now that you have Mage.exe and your imported certificate, you can sign a file. You need to know the certificate's SHA-1 hash, or *thumbprint*. The thumbprint ensures that Mage.exe only uses certificates verified by AWS CloudHSM. In this example, we use PowerShell to get the certificate's hash.

**To obtain a certificate's thumbprint and use it to sign a file**

1. Navigate to the directory containing `mage.exe`. The default location is:

   ```
   C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8.1 Tools\x64
   ```

1. To create a sample application file using Mage.exe, run the following command:

   ```
   mage.exe -New Application -ToFile C:\Users\Administrator\Desktop\sample.application
   ```

1. Open PowerShell as an administrator and run the following command:

   ```
   Get-ChildItem -path cert:\LocalMachine\My
   ```

   Copy the `Thumbprint`, `Key Container`, and `Provider` values from the output.  
![\[The certificate's hash will be displayed as the thumbprint, keycontainer and provider in the output\]](http://docs.aws.amazon.com/cloudhsm/latest/userguide/images/certstore-my-certificate.png)

1. Sign your file by running the following command:

   ```
   mage.exe -Sign -CertHash <thumbprint> -KeyContainer <keycontainer> -CryptoProvider <CloudHSM Key Storage Provider/Cavium Key Storage Provider> C:\Users\Administrator\Desktop\<sample.application>
   ```

   If the command is successful, PowerShell returns a success message.

1. To verify the signature on the file, use the following command:

   ```
   mage.exe -Verify -CryptoProvider <CloudHSM Key Storage Provider/Cavium Key Storage Provider> C:\Users\Administrator\Desktop\<sample.application>
   ```

# Other third-party vendor integrations with AWS CloudHSM
<a name="other-integrations"></a>

Several third-party vendors support AWS CloudHSM as a root of trust. This means that you can utilize a software solution of your choice while creating and storing the underlying keys in your CloudHSM cluster. As a result, your workload in AWS can rely on the latency, availability, reliability, and elasticity benefits of CloudHSM. The following list includes third-party vendors that support CloudHSM.

**Note**  
AWS does not endorse or vouch for any third-party vendor.
+ **[Hashicorp Vault](https://www.hashicorp.com)** is a secrets management tool designed to enable collaboration and governance across organizations. It supports AWS Key Management Service and AWS CloudHSM as roots of trust for additional protection.
+ **[Thycotic Secrets Server](https://thycotic.com)** helps customers manage sensitive credentials across privileged accounts. It supports AWS CloudHSM as a root of trust. 
+ **[P6R's KMIP adapter](https://www.p6r.com/software/ksg.html)** allows you to utilize your AWS CloudHSM instances through a standard KMIP interface. 
+ **[PrimeKey EJBCA](https://aws.amazon.com/marketplace/seller-profile?id=7edf9048-58e6-4086-9d98-b8e0c1d78fce)** is a popular open source solution for PKI. It allows you to create and store key pairs securely with AWS CloudHSM. 
+ **[Box KeySafe](https://blog.box.com)** provides encryption key management for cloud content to many organizations with strict security, privacy, and regulatory compliance requirements. Customers can further secure KeySafe keys directly in AWS Key Management Service or indirectly in AWS CloudHSM via AWS KMS Custom Key Store.
+ **[Insyde Software](https://www.insyde.com)** supports AWS CloudHSM as a root of trust for firmware signing. 
+ **[F5 BIG-IP LTM](https://techdocs.f5.com)** supports AWS CloudHSM as a root of trust. 
+ **[Cloudera Navigator Key HSM](https://www.cloudera.com)** allows you to use your CloudHSM cluster to create and store keys for Cloudera Navigator Key Trustee Server. 
+ **[Venafi Trust Protection Platform](https://marketplace.venafi.com/details/aws-cloudhsm/)** provides comprehensive machine identity management for TLS, SSH, and code signing with AWS CloudHSM key generation and protection.