

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# AWS CloudHSM JCE for Client SDK 5 的進階組態
<a name="java-lib-configs"></a>

 AWS CloudHSM JCE 供應商包含下列進階組態，這些組態不屬於大多數客戶使用的一般組態。
+ [連接至多個叢集](java-lib-configs-multi.md)
+ [使用 JCE 擷取金鑰](java-lib-configs-getencoded.md)
+ [重試適用於 JCE 的組態](java-lib-configs-retry.md)

# 使用 JCE 提供者連線至多個 AWS CloudHSM 叢集
<a name="java-lib-configs-multi"></a>

此組態允許單一用戶端執行個體與多個 AWS CloudHSM 叢集通訊。與單一執行個體僅能與單一叢集進行通訊相比，該組態可節省某些使用案例的成本。`CloudHsmProvider` 類別 AWS CloudHSM是 [Java Security 提供者類別](https://docs.oracle.com/javase/8/docs/api/java/security/Provider.html)的實作。此類別的每個執行個體都代表整個 AWS CloudHSM 叢集的連線。您可以將此類別實例化，並將其新增至 Java 安全提供者清單中，以便您可以使用標準的 JCE 類別與其進行互動。

下面範例會將此類別實例化，並將其新增至 Java 安全提供者清單：

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

可以使用下列兩種方式來對 `CloudHsmProvider` 進行設定：

1. 使用檔案進行設定 (預設組態)

1. 使用程式碼設定

下列主題說明這些組態，以及如何連線至多個叢集。

**Topics**
+ [使用 檔案設定 AWS CloudHSM `CloudHsmProvider`類別 （預設組態）](java-lib-configs-default.md)
+ [使用程式碼設定類別 AWS CloudHSM `CloudHsmProvider`](java-lib-configs-using-code.md)
+ [連線至多個 AWS CloudHSM 叢集](java-lib-connecting-to-multiclusters.md)

# 使用 檔案設定 AWS CloudHSM `CloudHsmProvider`類別 （預設組態）
<a name="java-lib-configs-default"></a>

設定 AWS CloudHSM `CloudHsmProvider`類別的預設方法是使用 檔案。

當您使用預設建構函數實例化 `CloudHsmProvider` 時，根據預設，它會在 Linux 的 `/opt/cloudhsm/etc/cloudhsm-jce.cfg` 路徑中尋找組態檔案。可使用 `configure-jce` 設定此組態檔案。

使用預設的建構函數所建立的物件將會使用預設的 CloudHSM 提供者名稱 `CloudHSM`。提供者名稱有助於與 JCE 進行互動，以讓它了解各種作業應使用哪個提供者。以下為使用 CloudHSM 提供者名稱進行加密作業的範例：

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

# 使用程式碼設定類別 AWS CloudHSM `CloudHsmProvider`
<a name="java-lib-configs-using-code"></a>

從用戶端 SDK 5.8.0 版開始，您也可以使用 Java 程式碼來設定 AWS CloudHSM `CloudHsmProvider`類別。使用 `CloudHsmProviderConfig` 類別的物件可以進行設定。您可以使用 `CloudHsmProviderConfigBuilder` 建置此物件。

`CloudHsmProvider` 有另一個接受 `CloudHsmProviderConfig` 物件的建構函數，如下列範例顯示。

**Example**  

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

在此範例中，JCE 提供者的名稱為 `CloudHsmCluster1`。這是應用程式接著可用來與 JCE 互動的名稱：

**Example**  

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

或者，應用程式還可以使用上面建立的提供者物件，讓 JCE 了解要使用該提供者以進行作業：

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

如果未使用 `withClusterUniqueIdentifier` 方法指定唯一識別碼，則會為您建立一個隨機產生的提供者名稱。若要取得此隨機產生的識別碼，應用程式可以呼叫 `provider.getName()` 以取得識別碼。

# 連線至多個 AWS CloudHSM 叢集
<a name="java-lib-connecting-to-multiclusters"></a>

每個 `CloudHsmProvider`代表 AWS CloudHSM 叢集的連線。如果您想要從同一個應用程式與另一個叢集進行通訊，您可以使用其他叢集的組態建立另一個物件 `CloudHsmProvider`，然後您可以使用提供者物件或使用提供者名稱與該叢集互動，如下列範例所顯示。

**Example**  

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

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

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

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

設定上述兩個提供者 (兩個叢集) 後，您可以使用提供者物件或使用提供者名稱與其進行互動。

此範例顯示了如何與 `cluster1` 進行通訊，在此基礎上，您可以使用下列範例進行 AES/GCM/NoPadding 操作。

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

在同一個應用程序中使用提供者名稱在第二個叢集上產生「AES」金鑰，您還可以使用下列範例：

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

# 使用 JCE for 擷取金鑰 AWS CloudHSM
<a name="java-lib-configs-getencoded"></a>

Java 密碼編譯延伸模組 (JCE) 使用允許插入不同密碼編譯實作的架構。 AWS CloudHSM 會運送其中一個 JCE 提供者，將密碼編譯操作卸載至 HSM。對於使用儲存在 AWS CloudHSM 中金鑰的其他大多數 JCE 提供者，他們必須將金鑰位元組以純文字形式從 HSM 擷取到機器的記憶體中以供使用。HSM 通常僅允許將金鑰擷取為包裝物件，而非純文字。不過，為了支援供應商間整合使用案例， AWS CloudHSM 允許選擇加入組態選項，以明確地擷取金鑰位元組。

**重要**  
只要指定 AWS CloudHSM 供應商或使用 AWS CloudHSM 金鑰物件，JCE AWS CloudHSM 就會將操作卸載至 。如果您預期在 HSM 內進行作業，則您不需要以純文字形式擷取金鑰。當您的應用程式因第三方程式庫或 JCE 提供者的限制而無法使用安全機制 (例如，包裝和取消包裝金鑰) 時，僅需要以純文字形式擷取金鑰。

根據預設， AWS CloudHSM JCE 提供者允許擷取**公有金鑰**以使用外部 JCE 提供者。一律允許使用下列方法：


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

根據預設， AWS CloudHSM JCE 提供者不允許擷取**私有**或**私密**金鑰的清除金鑰位元組。如果您的使用案例需要，您可在下列情況下以純文字形式擷取**私用**金鑰或**秘密**金鑰的金鑰位元組：

1. 私用金鑰和秘密金鑰的 `EXTRACTABLE` 屬性設定為 **true**。
   + 根據預設，私用金鑰和秘密金鑰的 `EXTRACTABLE` 屬性設定為 **true**。`EXTRACTABLE` 金鑰是允許從 HSM 匯出的金鑰。如需詳細資訊，請參閱 [Client SDK 5](java-lib-attributes_5.md) 支援的 Java 屬性。

1. 私用金鑰和私密金鑰的 `WRAP_WITH_TRUSTED` 屬性設定為 **false**。
   + `getEncoded`、`getPrivateExponent` 和 `getS` 不能與無法以純文字形式匯出的私用金鑰搭配使用。`WRAP_WITH_TRUSTED` 不允許您的私用金鑰以純文字形式匯出 HSM。如需詳細資訊，請參閱[使用受信任的金鑰控制金鑰取消包裝](manage-keys-using-trusted-keys.md)。

# 允許 JCE 提供者從 中擷取私有金鑰秘密 AWS CloudHSM
<a name="get-encoded-take-out-private-keys"></a>

使用下列步驟允許 AWS CloudHSM JCE 提供者擷取您的私有金鑰秘密。

**重要**  
變更此組態後，就可以從 HSM 叢集以純文字形式擷取所有 `EXTRACTABLE` 金鑰位元組。為了獲得更好的安全性，您應考慮使用[金鑰包裝方法](java-lib-supported_5.md)將金鑰安全地從 HSM 擷取出來。這可防止意外從 HSM 擷取金鑰位元組。

1. 使用下列命令，可在 JCE 中啟用您的**私用**金鑰或**秘密**金鑰：

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

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

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

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

------

1. 啟用以純文字形式擷取金鑰後，即可啟用下列方法將私用金鑰擷取至記憶體。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/cloudhsm/latest/userguide/get-encoded-take-out-private-keys.html)

如果您想還原預設行為，且不允許 JCE 以純文字形式匯出金鑰，請執行下列命令：

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

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

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

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

------

# 重試適用於 的 JCE 命令 AWS CloudHSM
<a name="java-lib-configs-retry"></a>

AWS CloudHSM 用戶端 SDK 5.8.0 和更新版本具有內建的自動重試策略，將從用戶端重試 HSM 限流操作。當 HSM 因過於忙於執行先前操作而無法接受更多要求而限制操作時，用戶端 SDK 會嘗試重試限流操作 (最多 3 次)，同時以指数形式回退。此自動重試策略可以設定為兩種模式中的其中一種：**關閉**模式和**標準**模式。
+ **關閉**：用戶端 SDK 將不會針對 HSM 的任何限流操作執行任何重試政策。
+ **標準**：這是用戶端 SDK 5.8.0 及更新版本的預設模式。在此模式下，用戶端 SDK 會以指數回退形式自動重試限流操作。

如需詳細資訊，請參閱[HSM 調節](troubleshoot-hsm-throttling.md)。

## 將重試命令設定為關閉模式
<a name="w2aac25c21c25c25c15b9"></a>

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

**將 Linux 上用戶端 SDK 5 重試命令設定為 **off****
+ 您可以使用下列命令將重試組態設定為 **off** 模式：

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

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

**將 Windows 上用戶端 SDK 5 重試命令設定為 **off****
+ 您可以使用下列命令將重試組態設定為 **off** 模式：

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

------