

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

# 將您的 JCE 供應商從 AWS CloudHSM 用戶端 SDK 3 遷移至用戶端 SDK 5
<a name="java-lib-migrate_to_sdk5"></a>

使用此主題將 [JCE 供應商](java-library.md)從 AWS CloudHSM 用戶端 SDK 3 遷移至用戶端 SDK 5。如需遷移的優勢，請參閱 [AWS CloudHSM 用戶端 SDK 5 的優點](client-sdk-5-benefits.md)。

在 中 AWS CloudHSM，客戶應用程式會使用 AWS CloudHSM 用戶端軟體開發套件 (SDK) 執行密碼編譯操作。用戶端 SDK 5 是主要 SDK，會持續新增新功能和平台支援。

用戶端 SDK 3 JCE 提供者使用不屬於標準 JCE 規格的自訂類別和 APIs。適用於 JCE 提供者的用戶端 SDK 5 會抱怨 JCE 規格，且與特定區域的用戶端 SDK 3 回溯不相容。在遷移至用戶端 SDK 5 的過程中，客戶應用程式可能需要變更。本節概述成功遷移所需的變更。

若要檢閱所有供應商的遷移說明，請參閱 [從 AWS CloudHSM 用戶端 SDK 3 遷移至用戶端 SDK 5](client-sdk-migration.md)。

**Topics**
+ [解決重大變更以做好準備](#jce-migration-preparation-sdk5)
+ [遷移至用戶端 SDK 5](#w2aac25c19c21c15)
+ [相關主題](#java-lib-migrate_to_sdk5-seealso)

## 解決重大變更以做好準備
<a name="jce-migration-preparation-sdk5"></a>

檢閱這些重大變更，並相應地更新開發環境中的應用程式。

### 供應商類別和名稱已變更
<a name="w2aac25c19c21c13b5"></a>


****  

| 已變更的內容 | 用戶端 SDK 3 中的內容 | 用戶端 SDK 5 中的內容 | 範例 | 
| --- | --- | --- | --- | 
| 供應商類別和名稱 | 用戶端 SDK 3 中的 JCE 提供者類別稱為 `CaviumProvider`，且具有提供者名稱 `Cavium`。 | 在用戶端 SDK 5 中，稱為提供者類別`CloudHsmProvider`，且具有提供者名稱 `CloudHSM`。 | 有關如何初始化`CloudHsmProvider`物件的範例可在 [AWS CloudHSM GitHub 範例儲存庫](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/AESGCMEncryptDecryptRunner.java#L43-L50)中找到。 | 

### 明確登入已變更，隱含 尚未
<a name="w2aac25c19c21c13b7"></a>


****  

| 已變更的內容 | 用戶端 SDK 3 中的內容 | 用戶端 SDK 5 中的內容 | 範例 | 
| --- | --- | --- | --- | 
| 明確登入 | 用戶端 SDK 3 使用 `LoginManager`類別進行明確登入[1](#explicit_login_sdk3_note)。 | 在用戶端 SDK 5 中，`CloudHSM`提供者會實作 `AuthProvider`以進行明確登入。 `AuthProvider` 是標準 Java 類別，並遵循 Java 的慣用方式登入提供者。透過改善用戶端 SDK 5 中的登入狀態管理，應用程式不再需要在重新連線期間監控和執行登入[2](#explicit_login_sdk5_note)。 | 如需如何搭配用戶端 SDK 5 使用明確登入的範例，請參閱 AWS CloudHSM GitHub 範例儲存庫中的 LoginRunner 範例。 [AWS CloudHSM GitHub ](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/LoginRunner.java#L109C5-L141) | 
| 隱含登入 | 隱含登入不需要變更。從用戶端 SDK 3 遷移到用戶端 SDK 5 時，相同的屬性檔案和所有環境變數將繼續用於隱含登入。 | 如需如何搭配用戶端 SDK 5 使用隱含登入的範例，請參閱 AWS CloudHSM GitHub [範例儲存庫中的 LoginRunner ](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/LoginRunner.java#L143-L202) 範例。 | 
+ 【1】 用戶端 SDK 3 程式碼片段：

  ```
  LoginManager lm = LoginManager.getInstance();
                         
  lm.login(partition, user, pass);
  ```
+ 【2】 用戶端 SDK 5 程式碼片段：

  ```
  // Construct or get the existing provider object 
  AuthProvider provider = new CloudHsmProvider();
                         
  // Call login method on the CloudHsmProvider object
  // Here loginHandler is a CallbackHandler
  provider.login(null, loginHandler);
  ```

  如需如何搭配用戶端 SDK 5 使用明確登入的範例，請參閱 AWS CloudHSM GitHub [範例儲存庫中的 LoginRunner ](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/LoginRunner.java#L109C5-L141) 範例。

### 金鑰產生已變更
<a name="w2aac25c19c21c13b9"></a>


****  

| 已變更的內容 | 用戶端 SDK 3 中的內容 | 用戶端 SDK 5 中的內容 | 範例 | 
| --- | --- | --- | --- | 
| 金鑰產生 | 在用戶端 SDK 3 中， `Cavium[Key-type]AlgorithmParameterSpec` 用於指定金鑰產生參數。如需程式碼片段，請參閱註腳 [1](#key_generation_sdk3_note)。 | 在用戶端 SDK 5 中， `KeyAttributesMap` 用於指定金鑰產生屬性。如需程式碼片段，請參閱註腳 [2](#key_generation_sdk5_note)。 | 如需如何使用 `KeyAttributesMap`產生對稱金鑰的範例，請參閱 AWS CloudHSM GitHub [範例儲存庫中的 SymmetricKeys ](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/SymmetricKeys.java) 範例。 | 
| 產生金鑰對 | 在用戶端 SDK 3 中， `Cavium[Key-type]AlgorithmparameterSpec` 用於指定金鑰對產生參數。如需程式碼片段，請參閱註腳 [3](#key_pair_generation_sdk3_note)。 | 在用戶端 SDK 5 中， `KeyPairAttributesMap` 用於指定這些參數。如需程式碼片段，請參閱註腳 [4](#key_pair_generation_sdk5_note)。 | 如需如何使用 `KeyAttributesMap`產生非對稱金鑰的範例，請參閱 AWS CloudHSM GitHub [範例儲存庫中的 AsymmetricKeys ](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/AsymmetricKeys.java) 範例。 | 
+ 【1】 用戶端 SDK 3 金鑰產生程式碼片段：

  ```
  KeyGenerator keyGen = KeyGenerator.getInstance("AES", "Cavium");
  CaviumAESKeyGenParameterSpec aesSpec = new CaviumAESKeyGenParameterSpec(
  keySizeInBits,
  keyLabel,
  isExtractable,
  isPersistent);
  keyGen.init(aesSpec);
  SecretKey aesKey = keyGen.generateKey();
  ```
+ 【2】 用戶端 SDK 5 金鑰產生程式碼片段：

  ```
  KeyGenerator keyGen = KeyGenerator.getInstance("AES",
  CloudHsmProvider.PROVIDER_NAME);
                      
  final KeyAttributesMap aesSpec = new KeyAttributesMap();
  aesSpec.put(KeyAttribute.LABEL, keyLabel);
  aesSpec.put(KeyAttribute.SIZE, keySizeInBits);
  aesSpec.put(KeyAttribute.EXTRACTABLE, isExtractable);
  aesSpec.put(KeyAttribute.TOKEN, isPersistent);
                      
  keyGen.init(aesSpec);
  SecretKey aesKey = keyGen.generateKey();
  ```
+ 【3】 用戶端 SDK 3 金鑰對產生程式碼片段：

  ```
  KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("rsa", "Cavium");
  CaviumRSAKeyGenParameterSpec spec = new CaviumRSAKeyGenParameterSpec(
  keySizeInBits,
  new BigInteger("65537"),
  label + ":public",
  label + ":private",
  isExtractable,
  isPersistent);
                      
  keyPairGen.initialize(spec);
                      
  keyPairGen.generateKeyPair();
  ```
+ 【4】 用戶端 SDK 5 金鑰對產生程式碼片段：

  ```
  KeyPairGenerator keyPairGen =
  KeyPairGenerator.getInstance("RSA", providerName);
                      
  // Set attributes for RSA public key
  final KeyAttributesMap publicKeyAttrsMap = new KeyAttributesMap();
  publicKeyAttrsMap.putAll(additionalPublicKeyAttributes);
  publicKeyAttrsMap.put(KeyAttribute.LABEL, label + ":Public");
  publicKeyAttrsMap.put(KeyAttribute.MODULUS_BITS, keySizeInBits);
  publicKeyAttrsMap.put(KeyAttribute.PUBLIC_EXPONENT,
  new BigInteger("65537").toByteArray());
                      
  // Set attributes for RSA private key
  final KeyAttributesMap privateKeyAttrsMap = new KeyAttributesMap();
  privateKeyAttrsMap.putAll(additionalPrivateKeyAttributes);
  privateKeyAttrsMap.put(KeyAttribute.LABEL, label + ":Private");
                      
  // Create KeyPairAttributesMap and use that to initialize the 
  // keyPair generator
  KeyPairAttributesMap keyPairSpec =
  new KeyPairAttributesMapBuilder()
  .withPublic(publicKeyAttrsMap)
  .withPrivate(privateKeyAttrsMap)
  .build();
                      
  keyPairGen.initialize(keyPairSpec);
  keyPairGen.generateKeyPair();
  ```

### 尋找、刪除和參考金鑰已變更
<a name="w2aac25c19c21c13c11"></a>

 AWS CloudHSM 使用 KeyStore 尋找已產生的金鑰。用戶端 SDK 3 有兩種 KeyStore 類型： `Cavium`和 `CloudHSM`。用戶端 SDK 5 只有一種 KeyStore 類型：`CloudHSM`。

從 `Cavium` KeyStore 移至 `CloudHSM` KeyStore 需要變更 KeyStore 類型。此外，用戶端 SDK 3 使用金鑰控制代碼來參考金鑰，而用戶端 SDK 5 則使用金鑰標籤。產生的行為變更如下所示。


| 已變更的內容 | 用戶端 SDK 3 中的內容 | 用戶端 SDK 5 中的內容 | 範例 | 
| --- | --- | --- | --- | 
| 金鑰參考 | 透過用戶端 SDK 3，應用程式會使用金鑰標籤或金鑰控制代碼來參考 HSM 中的金鑰。他們使用標籤搭配 KeyStore 來尋找金鑰，或使用控點和建立`CaviumKey`物件。 | 在用戶端 SDK 5 中，應用程式可以使用 [用戶端 SDK 5 的AWS CloudHSM KeyStore Java 類別](alternative-keystore_5.md) 依標籤尋找金鑰。若要依控制代碼尋找金鑰，請使用 AWS CloudHSM `KeyStoreWithAttributes`搭配 AWS CloudHSM `KeyReferenceSpec`。 |  | 
| 尋找多個項目 | 在 KeyStore 中存在多個條件相同的項目`getCertificate`的情況下`getKey`，使用 `getEntry`、 或 搜尋`Cavium`金鑰時，只會傳回找到的第一個項目。 | 使用 AWS CloudHSM `KeyStore`和 時`KeyStoreWithAttributes`，這個相同的案例會導致擲回例外狀況。若要修正此問題，建議您使用 CloudHSM CLI 中的 [使用 CloudHSM CLI 設定金鑰的屬性](cloudhsm_cli-key-set-attribute.md)命令來設定金鑰的唯一標籤。或使用 `KeyStoreWithAttributes#getKeys` 傳回符合條件的所有金鑰。 |  | 
| 尋找所有金鑰 | 您可以在用戶端 SDK 3 中使用 尋找 HSM 中的所有金鑰`Util.findAllKeys()`。 | 用戶端 SDK 5 使用 `KeyStoreWithAttributes`類別，讓尋找金鑰變得更簡單且更有效率。盡可能快取您的金鑰，將延遲降至最低。如需詳細資訊，請參閱[有效管理應用程式中的金鑰](bp-application-integration.md#bp-manage-application)。當您需要從 HSM 擷取所有金鑰時，請使用 `KeyStoreWithAttributes#getKeys`搭配空的 `KeyAttributesMap`。 | 使用 `KeyStoreWithAttributes`類別尋找金鑰的範例可在 [AWS CloudHSM GitHub 範例儲存庫](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java#L205-L223)中使用，程式碼片段會顯示在 中[1](#using_keystore_att_note)。 | 
| 刪除金鑰 | 用戶端 SDK 3 使用 `Util.deleteKey()`刪除金鑰。 | 用戶端 SDK 5 中的 `Key` 物件實作 `Destroyable`界面，允許使用此界面的 `destroy()`方法刪除金鑰。 | 您可以在 [CloudHSM GitHub 範例儲存庫](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java#L229-L234)中找到顯示刪除金鑰功能的範例程式碼。每個 SDK 的範例程式碼片段會顯示在 中[2](#delete_key_note)。 | 
+ 【1】 程式碼片段如下所示：

  ```
  KeyAttributesMap findSpec = new KeyAttributesMap();
  findSpec.put(KeyAttribute.LABEL, label);
  findSpec.put(KeyAttribute.KEY_TYPE, keyType);
  KeyStoreWithAttributes keyStore = KeyStoreWithAttributes.getInstance("CloudHSM");
                      
  keyStore.load(null, null);
  keyStore.getKey(findSpec);
  ```
+ 【2】 在用戶端 SDK 3 中刪除金鑰：

  ```
  Util.deleteKey(key);
  ```

  在用戶端 SDK 5 中刪除金鑰：

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

### 密碼取消包裝操作已變更，其他密碼操作尚未
<a name="w2aac25c19c21c13c13"></a>

**注意**  
密碼encrypt/decrypt/wrap操作不需要變更。

取消包裝操作需要將用戶端 SDK 3 `CaviumUnwrapParameterSpec`類別取代為下列密碼編譯操作專用的其中一個類別。
+ `GCMUnwrapKeySpec` 用於`AES/GCM/NoPadding`取消包裝
+ `IvUnwrapKeySpec` 適用於 `AESWrap unwrap`和 的 `AES/CBC/NoPadding unwrap`
+ 適用於 `RSA OAEP unwrap` 的 `OAEPUnwrapKeySpec`

的範例程式碼片段`OAEPUnwrapkeySpec`：

```
OAEPParameterSpec oaepParameterSpec =
new OAEPParameterSpec(
        "SHA-256",
        "MGF1",
        MGF1ParameterSpec.SHA256,
        PSpecified.DEFAULT);

KeyAttributesMap keyAttributesMap =
        new KeyAttributesMap(KeyAttributePermissiveProfile.KEY_CREATION);
keyAttributesMap.put(KeyAttribute.TOKEN, true);
keyAttributesMap.put(KeyAttribute.EXTRACTABLE, false);

OAEPUnwrapKeySpec spec = new OAEPUnwrapKeySpec(oaepParameterSpec,
        keyAttributesMap);

Cipher hsmCipher =
        Cipher.getInstance(
                "RSA/ECB/OAEPPadding",
                CloudHsmProvider.PROVIDER_NAME);
hsmCipher.init(Cipher.UNWRAP_MODE, key, spec);
```

### 簽章操作尚未變更
<a name="w2aac25c19c21c13c15"></a>

Signature 操作不需要變更。

## 遷移至用戶端 SDK 5
<a name="w2aac25c19c21c15"></a>

遵循本節中的指示，從用戶端 SDK 3 遷移至用戶端 SDK 5。

**注意**  
用戶端 SDK 5 目前不支援 Amazon Linux、Ubuntu 16.04、Ubuntu 18.04 CentOS 6、CentOS 8 和 RHEL 6。如果您目前正在將其中一個平台與用戶端 SDK 3 搭配使用，則需要在遷移至用戶端 SDK 5 時選擇不同的平台。

1. 解除安裝用戶端 SDK 3 的 JCE 提供者。

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

   ```
   $ sudo yum remove cloudhsm-client-jce
   ```

------
#### [ CentOS 7 ]

   ```
   $ sudo yum remove cloudhsm-client-jce
   ```

------
#### [ RHEL 7 ]

   ```
   $ sudo yum remove cloudhsm-client-jce
   ```

------
#### [ RHEL 8 ]

   ```
   $ sudo yum remove cloudhsm-client-jce
   ```

------
#### [ Ubuntu 16.04 LTS ]

   ```
   $ sudo apt remove cloudhsm-client-jce
   ```

------
#### [ Ubuntu 18.04 LTS ]

   ```
   $ sudo apt remove cloudhsm-client-jce
   ```

------

1. 停止用戶端 SDK 3 的用戶端協助程式。

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

   ```
   $ sudo service cloudhsm-client stop
   ```

------
#### [ CentOS 7 ]

   ```
   $ sudo service cloudhsm-client stop
   ```

------
#### [ RHEL 7 ]

   ```
   $ sudo service cloudhsm-client stop
   ```

------
#### [ RHEL 8 ]

   ```
   $ sudo service cloudhsm-client stop
   ```

------
#### [ Ubuntu 16.04 LTS ]

   ```
   $ sudo systemctl stop cloudhsm-client
   ```

------
#### [ Ubuntu 18.04 LTS ]

   ```
   $ sudo systemctl stop cloudhsm-client
   ```

------

1. 解除安裝 Client Daemon for Client SDK 3。

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

   ```
   $ sudo yum remove cloudhsm-client
   ```

------
#### [ CentOS 7 ]

   ```
   $ sudo yum remove cloudhsm-client
   ```

------
#### [ RHEL 7 ]

   ```
   $ sudo yum remove cloudhsm-client
   ```

------
#### [ RHEL 8 ]

   ```
   $ sudo yum remove cloudhsm-client
   ```

------
#### [ Ubuntu 16.04 LTS ]

   ```
   $ sudo apt remove cloudhsm-client
   ```

------
#### [ Ubuntu 18.04 LTS ]

   ```
   $ sudo apt remove cloudhsm-client
   ```

------
**注意**  
需要再次啟用自訂組態。

1. 依照中的步驟安裝用戶端 SDK JCE 提供者[安裝 AWS CloudHSM 用戶端 SDK 5 的 JCE 提供者](java-library-install_5.md)。

1. 用戶端 SDK 5 推出新的組態檔案格式和命令列引導工具。若要引導您的用戶端 SDK 5 JCE 供應商，請遵循 下使用者指南中列出的說明[引導用戶端 SDK](cluster-connect.md#connect-how-to)。

1. 在您的開發環境中，測試您的應用程式。更新現有程式碼，以在最終遷移之前解決重大變更。

## 相關主題
<a name="java-lib-migrate_to_sdk5-seealso"></a>
+ [的最佳實務 AWS CloudHSM](best-practices.md)