

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将您的 JCE 提供程序从 AWS CloudHSM 客户端 SDK 3 迁移到客户端 SDK 5
<a name="java-lib-migrate_to_sdk5"></a>

使用本主题将您的 [JCE 提供程序](java-library.md)从 AWS CloudHSM Client SDK 3 迁移到 Client SDK 5。有关迁移的好处，请参阅 [AWS CloudHSM 客户端 SDK 的好处 5](client-sdk-5-benefits.md)。

在中 AWS CloudHSM，客户应用程序使用 AWS CloudHSM 客户端软件开发套件 (SDK) 执行加密操作。Client SDK 5 是主要 SDK，它不断添加新功能和平台支持。

客户端 SDK 3 JCE 提供程序使用自定义类 APIs ，这些类不属于标准 JCE 规范。JCE 提供程序的 Client SDK 5 不符合 JCE 规范，并且在某些方面与 Client SDK 3 向后不兼容。在迁移到 Client SDK 5 的过程中，可能需要对客户应用程序进行更改。本节概述了成功迁移所需的更改。

要查看所有提供程序的迁移说明，请参阅 [从 AWS CloudHSM 客户端 SDK 3 迁移到客户端 SDK 5](client-sdk-migration.md)。

**Topics**
+ [通过解决重大更改做好准备](#jce-migration-preparation-sdk5)
+ [迁移到 Client SDK 5](#w2aac25c19c21c15)
+ [相关主题](#java-lib-migrate_to_sdk5-seealso)

## 通过解决重大更改做好准备
<a name="jce-migration-preparation-sdk5"></a>

查看这些重大更改，并在开发环境中相应地更新您的应用程序。

### 提供程序类和名称已更改
<a name="w2aac25c19c21c13b5"></a>


****  

| 已更改的内容 | Client SDK 3 中的内容 | Client SDK 5 中的内容 | 示例 | 
| --- | --- | --- | --- | 
| 提供程序类和名称 | Client SDK 3 中的 JCE 提供程序类称为 `CaviumProvider`，提供程序名称为 `Cavium`。 | 在 Client 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>


****  

| 已更改的内容 | Client SDK 3 中的内容 | Client SDK 5 中的内容 | 示例 | 
| --- | --- | --- | --- | 
| 显式登录 | Client SDK 3 使用 `LoginManager` 类进行显式登录 [1](#explicit_login_sdk3_note)。 | 在 Client SDK 5 中，`CloudHSM` 提供程序实现 `AuthProvider` 来进行显式登录。`AuthProvider` 是一个标准 Java 类，它遵循 Java 的惯用方式登录提供程序。借助 Client SDK 5 中改进的登录状态管理，应用程序不再需要在重新连接期间监控和执行登录[2](#explicit_login_sdk5_note)。 | 有关如何在客户端软件开发工具包 5 中使用显式登录的示例，请参阅 [AWS Cloud GitHub H](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/LoginRunner.java#L109C5-L141) SM LoginRunner 示例存储库中的示例。 | 
| 隐式登录 | 隐式登录无需进行任何更改。从 Client SDK 3 迁移到 Client SDK 5 时，相同的属性文件和所有环境变量将继续适用于隐式登录。 | 有关如何在 Client SDK 5 中使用隐式登录的示例，请参阅[LoginRunner 示例](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/LoginRunner.java#L143-L202)存储库中的 AWS CloudHSM GitHub 示例。 | 
+ [1] Client SDK 3 代码片段：

  ```
  LoginManager lm = LoginManager.getInstance();
                         
  lm.login(partition, user, pass);
  ```
+ [2] Client 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);
  ```

  有关如何在 Client SDK 5 中使用显式登录的示例，请参阅[LoginRunner 示例](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/LoginRunner.java#L109C5-L141)存储库中的 AWS CloudHSM GitHub 示例。

### 密钥生成已更改
<a name="w2aac25c19c21c13b9"></a>


****  

| 已更改的内容 | Client SDK 3 中的内容 | Client SDK 5 中的内容 | 示例 | 
| --- | --- | --- | --- | 
| 密钥生成 | 在 Client SDK 3 中，`Cavium[Key-type]AlgorithmParameterSpec` 用于指定密钥生成参数。有关代码片段，请参阅脚注 [1](#key_generation_sdk3_note)。 | 在 Client SDK 5 中，`KeyAttributesMap` 用于指定密钥生成属性。有关代码片段，请参阅脚注 [2](#key_generation_sdk5_note)。 | 有关如何使用`KeyAttributesMap`生成对称密钥的示例，请参阅 AW GitHub S CloudHSM [SymmetricKeys 示例存储库中的示例](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/SymmetricKeys.java)。 | 
| 密钥对生成 | 在 Client SDK 3 中，`Cavium[Key-type]AlgorithmparameterSpec` 用于指定密钥对生成参数。有关代码片段，请参阅脚注 [3](#key_pair_generation_sdk3_note)。 | 在 Client SDK 5 中，`KeyPairAttributesMap` 用于指定这些参数。有关代码片段，请参阅脚注 [4](#key_pair_generation_sdk5_note)。 | 有关如何使用`KeyAttributesMap`生成非对称密钥的示例，请参阅[AsymmetricKeys 示例](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/AsymmetricKeys.java)存储库中的 AWS CloudHSM GitHub 示例。 | 
+ [1] Client SDK 3 密钥生成代码片段：

  ```
  KeyGenerator keyGen = KeyGenerator.getInstance("AES", "Cavium");
  CaviumAESKeyGenParameterSpec aesSpec = new CaviumAESKeyGenParameterSpec(
  keySizeInBits,
  keyLabel,
  isExtractable,
  isPersistent);
  keyGen.init(aesSpec);
  SecretKey aesKey = keyGen.generateKey();
  ```
+ [2] Client 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] Client 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] Client 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 类型。此外，Client SDK 3 使用密钥句柄来引用密钥，而 Client SDK 5 使用密钥标签。下面列出了由此产生的行为更改。


| 已更改的内容 | Client SDK 3 中的内容 | Client SDK 5 中的内容 | 示例 | 
| --- | --- | --- | --- | 
| 密钥引用 | 在 Client SDK 3 中，应用程序使用密钥标签或密钥句柄来引用 HSM 中的密钥。他们使用标签 KeyStore 来查找钥匙，或者他们使用手柄创建`CaviumKey`对象。 | 在 Client SDK 5 中，应用程序可以使用 [AWS CloudHSM KeyStore 适用于客户端 SDK 5 的 Java 类](alternative-keystore_5.md) 按标签查找密钥。要按手柄查找按键，请 AWS CloudHSM `KeyStoreWithAttributes`使用 with AWS CloudHSM `KeyReferenceSpec`。 |  | 
| 查找多个条目 | 使用`getEntry`、或搜索密钥时`getKey`，如果`getCertificate`中存在多个具有相同条件的项目 `Cavium` KeyStore，则只会返回找到的第一个条目。 | 使用 AWS CloudHSM `KeyStore`和`KeyStoreWithAttributes`，同样的场景将导致引发异常。要解决此问题，建议使用 CloudHSM CLI 中的 [使用 CloudHSM CLI 设置密钥的属性](cloudhsm_cli-key-set-attribute.md) 命令为密钥设置唯一标签。或者使用 `KeyStoreWithAttributes#getKeys` 返回所有符合条件的密钥。 |  | 
| 查找所有密钥 | 在 Client SDK 3 中，可以使用 `Util.findAllKeys()` 查找 HSM 中的所有密钥。 | Client 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) | 
| 删除密钥 | Client SDK 3 使用 `Util.deleteKey()` 删除密钥。 | Client SDK 5 中的 `Key` 对象实现了 `Destroyable` 接口，这样做允许使用此接口的 `destroy()` 方法删除密钥。 | 在 [Cloud GitHub HSM](https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/sdk5/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java#L229-L234) 示例存储库中可以找到显示删除密钥功能的示例代码。[2](#delete_key_note) 中显示了每个 SDK 的示例片段。 | 
+ [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] 在 Client SDK 3 中删除密钥：

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

  在 Client SDK 5 中删除密钥：

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

### 密码解包操作已更改，其他密码操作未更改
<a name="w2aac25c19c21c13c13"></a>

**注意**  
Cipher encrypt/decrypt/wrap 操作无需进行任何更改。

解包操作需要将 Client 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>

无需对签名操作进行任何更改。

## 迁移到 Client SDK 5
<a name="w2aac25c19c21c15"></a>

按照本节中的说明从 Client SDK 3 迁移到 Client SDK 5。

**注意**  
Client SDK 5 当前不支持 Amazon Linux、Ubuntu 16.04、Ubuntu 18.04 CentOS 6、CentOS 8 和 RHEL 6。如果您当前正在将其中一个平台与 Client SDK 3 结合使用，则在迁移到 Client SDK 5 时，您需要选择其他平台。

1. 卸载 Client 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. 停止 Client 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 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. 按照 [为 AWS CloudHSM 客户端 SDK 5 安装 JCE 提供程序](java-library-install_5.md) 中的步骤安装 Client SDK JCE 提供程序。

1. Client SDK 5 引入了一种新的配置文件格式和命令行引导工具。要引导您的 Client SDK 5 JCE 提供程序，请按照 [引导客户端软件开发工具包](cluster-connect.md#connect-how-to) 下的用户指南中列出的说明进行操作。

1. 在您的开发环境中，测试您的应用程序。在最终迁移之前，更新现有代码以解决重大更改。

## 相关主题
<a name="java-lib-migrate_to_sdk5-seealso"></a>
+ [的最佳实践 AWS CloudHSM](best-practices.md)