使用客户端软件开发工具包 5 与 Java Keytool 和 Jarsigner 集成 - AWS CloudHSM

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

使用客户端软件开发工具包 5 与 Java Keytool 和 Jarsigner 集成

AWS CloudHSM 密钥存储是一种特殊用途的 JCE 密钥存储区,它通过第三方工具(如和)使用与 HSM 上的密钥关联的证书。keytool jarsigner AWS CloudHSM 不在 HSM 上存储证书,因为证书是公开的非机密数据。 AWS CloudHSM 密钥库将证书存储在本地文件中,并将证书映射到您的 HSM 上的相应密钥。

当您使用密 AWS CloudHSM 钥库生成新密钥时,本地密钥存储文件中不会生成任何条目——密钥是在 HSM 上创建的。同样,当您使用 AWS CloudHSM 密钥库搜索密钥时,搜索将传递到 HSM。当您将证书存储在 AWS CloudHSM 密钥库中时,提供程序会验证 HSM 上是否存在具有相应别名的密钥对,然后将提供的证书与相应的密钥对相关联。

先决条件

要使用 AWS CloudHSM 密钥库,必须先初始化并配置 AWS CloudHSM JCE SDK。

步骤 1:安装 JCE

要安装 JCE,包括 AWS CloudHSM 客户端先决条件,请按照安装 Java 库的步骤进行操作。

步骤 2:将 HSM 登录凭证添加到环境变量

设置环境变量以包含 HSM 登录凭证。

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>
注意

AWS CloudHSM JCE 提供各种登录选项。要将 AWS CloudHSM 密钥存储用于第三方应用程序,必须使用带环境变量的隐式登录。如果要通过应用程序代码使用显式登录,则必须使用 AWS CloudHSM 密钥库构建自己的应用程序。有关更多信息,请参阅有关使用 AWS CloudHSM 密钥库的文章。

步骤 3:注册 JCE 提供程序

要在 Java CloudProvider 配置中注册 JCE 提供程序,请执行以下步骤:

  1. 在 Java 安装中打开 java.security 配置文件进行编辑。

  2. java.security 配置文件中,添加 com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider 作为最后一个提供程序。例如,如果 java.security 文件中有 9 个提供程序,则将以下提供程序添加为本节中的最后一个提供程序:

    security.provider.10=com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider

注意

将 AWS CloudHSM 提供商添加为更高的优先级可能会对系统的性能产生负面影响,因为对于可以安全地卸载到软件的操作,将优先考虑 AWS CloudHSM 提供商。作为最佳实践,请务必指定要用于操作的提供商,无论是基于软件的提供商还是基于软件的提供商。 AWS CloudHSM

注意

在使用带有 AWS CloudHSM 密钥库的 keytool 生成密钥时指定 -providerName-providerclass-providerpath 命令行选项可能会导致错误。

使用带有 AWS CloudHSM keytool 的密钥库

Keytool 是一个常见的命令行实用程序,用于常见密钥和证书任务。有关 keytool 的完整教程不在 AWS CloudHSM 文档的讨论范围内。本文介绍了在通过密钥库用作信任根时,应与各种 AWS CloudHSM 密钥工具函数一起使用的特定参数。 AWS CloudHSM

在密钥库中 AWS CloudHSM 使用 keytool 时,请为任何 keytool 命令指定以下参数:

Linux
-storetype CLOUDHSM -J-classpath< '-J/opt/cloudhsm/java/*'>
Windows
-storetype CLOUDHSM -J-classpath<'-J"C:\Program Files\Amazon\CloudHSM\java\*"'>

如果要使用 AWS CloudHSM 密钥库创建新的密钥库文件,请参阅使用 AWS CloudHSM KeyStore。要使用现有密钥库,请使用 keytool 的 –keystore 参数指定密钥库的名称(包括路径)。如果您在 keytool 命令中指定了不存在的密钥存储文件,则 AWS CloudHSM 密钥库会创建一个新的密钥存储文件。

使用 keytool 创建新密钥

您可以使用 keytool 生成 AWS CloudHSM的 JCE SDK 支持的 RSA、AES 和 DESede 类型的密钥。

重要

通过 keytool 生成的密钥在软件中生成,然后 AWS CloudHSM 作为可提取的永久密钥导入到。

我们强烈建议在 keytool 之外生成不可导出的密钥,然后将相应的证书导入密钥库。如果您通过 keytool 和 Jarsigner 使用可提取的 RSA 或 EC 密钥,则提供程序会从中导出密钥, AWS CloudHSM 然后在本地使用该密钥进行签名操作。

如果您有多个客户端实例连接到您的 AWS CloudHSM 集群,请注意,在一个客户端实例的密钥库中导入证书不会自动使证书在其他客户端实例上可用。要在每个客户端实例上注册密钥和关联证书,您需要运行 Java 应用程序,如 使用 Keytool 生成 CSR 中所述。或者,您可以在一个客户端上进行必要的更改,并将生成的密钥库文件复制到其他每个客户端实例。

示例 1:生成对称 AES-256 密钥,并将其保存在工作目录中名为“my_keystore.store”的密钥库文件中。将 <secret label> 替换为唯一标签。

Linux
$ keytool -genseckey -alias <secret label> -keyalg aes \ -keysize 256 -keystore my_keystore.store \ -storetype CloudHSM -J-classpath '-J/opt/cloudhsm/java/*' \
Windows
PS C:\> keytool -genseckey -alias <secret label> -keyalg aes ` -keysize 256 -keystore my_keystore.store ` -storetype CloudHSM -J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'

示例 2:生成 RSA 2048 密钥对,并将其保存在工作目录中名为“my_keystore.store”的密钥库文件中。将 <RSA key pair label> 替换为唯一标签。

Linux
$ keytool -genkeypair -alias <RSA key pair label> \ -keyalg rsa -keysize 2048 \ -sigalg sha512withrsa \ -keystore my_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 my_keystore.store ` -storetype CLOUDHSM ` -J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'

您可以在 Java 库中找到支持的签名算法列表。

使用 Keytool 删除密钥

密 AWS CloudHSM 钥库不支持删除密钥。您可以使用 Destroyable 接口的销毁方法删除密钥。

((Destroyable) key).destroy();

使用 Keytool 生成 CSR

如果使用 OpenSSL 动态引擎,您可以在生成证书签名请求 (CSR) 时获得最大的灵活性。以下命令使用 keytool 为具有别名 my-key-pair 的密钥对生成 CSR。

Linux
$ keytool -certreq -alias <key pair label> \ -file my_csr.csr \ -keystore my_keystore.store \ -storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*'
Windows
PS C:\> keytool -certreq -alias <key pair label> ` -file my_csr.csr ` -keystore my_keystore.store ` -storetype CLOUDHSM ` -J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'
注意

要从 keytool 使用密钥对,该密钥对必须在指定的密钥库文件中包含一个条目。如果要使用在 keytool 之外生成的密钥对,则必须将密钥和证书元数据导入密钥库中。有关导入密钥库数据的说明,请参阅 使用 keytool 将中间证书和根证书导入 AWS CloudHSM 密钥存储库

使用 keytool 将中间证书和根证书导入 AWS CloudHSM 密钥存储库

要导入 CA 证书,您必须在新导入的证书上启用完整证书链的验证。以下命令是一个示例。

Linux
$ keytool -import -trustcacerts -alias rootCAcert \ -file rootCAcert.cert -keystore my_keystore.store \ -storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*'
Windows
PS C:\> keytool -import -trustcacerts -alias rootCAcert ` -file rootCAcert.cert -keystore my_keystore.store ` -storetype CLOUDHSM ` -J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'

如果您将多个客户端实例连接到 AWS CloudHSM 集群,则在一个客户端实例的密钥库中导入证书不会自动使该证书在其他客户端实例上可用。您必须在每个客户端实例上导入证书。

使用 keytool 从 AWS CloudHSM 密钥库中删除证书

以下命令举例说明了如何从 Java keytool 密钥库中删除证书。

Linux
$ keytool -delete -alias mydomain \ -keystore my_keystore.store \ -storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*'
Windows
PS C:\> keytool -delete -alias mydomain ` -keystore my_keystore.store ` -storetype CLOUDHSM ` -J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'

如果您将多个客户端实例连接到 AWS CloudHSM 集群,则删除一个客户端实例密钥存储中的证书不会自动从其他客户端实例中删除该证书。您必须删除每个客户端实例上的证书。

使用 keytool 将有效的证书导入 AWS CloudHSM 密钥库

签署证书签名请求 (CSR) 后,您可以将其导入 AWS CloudHSM 密钥库并将其与相应的密钥对关联。以下命令是一个示例。

Linux
$ keytool -importcert -noprompt -alias <key pair label> \ -file my_certificate.crt \ -keystore my_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 my_keystore.store ` -storetype CLOUDHSM ` -J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'

别名应该是密钥库中具有关联证书的密钥对。如果密钥是在 keytool 之外生成的,或者在其他客户端实例上生成的,则必须先将密钥和证书元数据导入密钥库中。

证书链必须是可验证的。如果无法验证证书,则可能需要将签名(证书颁发机构)证书导入密钥库,以便验证证书链。

使用 Keytool 导出证书

以下示例生成二进制 X.509 格式的证书。要导出人类可读的证书,请将 -rfc 添加到 -exportcert 命令中。

Linux
$ keytool -exportcert -alias <key pair label> \ -file my_exported_certificate.crt \ -keystore my_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 my_keystore.store ` -storetype CLOUDHSM ` -J-classpath '-J"C:\Program Files\Amazon\CloudHSM\java\*"'

在 Jarsigner 中使用 AWS CloudHSM 密钥库

Jarsigner 是一种流行的命令行实用程序,用于使用安全存储在 HSM 上的密钥对 JAR 文件进行签名。有关 Jarsigner 的完整教程不在 AWS CloudHSM 文档的讨论范围内。本节介绍了 Jarsigner 参数,您应该使用这些参数通过 AWS CloudHSM 密钥存储区 AWS CloudHSM 作为信任根进行签名和验证签名。

设置密钥和证书

在使用 Jarsigner 签署 JAR 文件之前,请确保您已设置或完成以下步骤:

  1. 按照 AWS CloudHSM 密钥库先决条件中的指导操作。

  2. 设置您的签名密钥以及相关的证书和证书链,这些证书和证书链应存储在当前服务器或客户端实例的 AWS CloudHSM 密钥存储中。在上创建密钥, AWS CloudHSM 然后将关联的元数据导入您的 AWS CloudHSM 密钥存储区。如果要使用 keytool 设置密钥和证书,请参阅 使用 keytool 创建新密钥。如果您使用多个客户端实例签署 JAR,请创建密钥并导入证书链。然后将生成的密钥库文件复制到每个客户端实例。如果您经常生成新密钥,您可能会发现将证书单独导入到每个客户端实例更容易。

  3. 整个证书链应该是可验证的。要使证书链可验证,您可能需要将 CA 证书和中间证书添加到 AWS CloudHSM 密钥库中。请参阅 使用 AWS CloudHSM 和 Jarsigner 签署 JAR 文件 中的代码片段,了解有关使用 Java 代码验证证书链的说明。如果您愿意,可以使用 keytool 导入证书。有关使用 keytool 的说明,请参阅 使用 keytool 将中间证书和根证书导入 AWS CloudHSM 密钥存储库

使用 AWS CloudHSM 和 Jarsigner 签署 JAR 文件

使用以下命令签署 JAR 文件:

Linux;

适用于 OpenJDK 8

jarsigner -keystore my_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>

适用于 OpenJDK 11、openJDK 17 和 OpenJDK 21

jarsigner -keystore my_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 my_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>

适用于 OpenJDK 11、openJDK 17 和 OpenJDK 21

jarsigner -keystore my_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>

使用以下命令验证已签名的 JAR:

Linux

For OpenJDK8

jarsigner -verify \ -keystore my_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>

适用于 OpenJDK 11、openJDK 17 和 OpenJDK 21

jarsigner -verify \ -keystore my_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

适用于 OpenJDK 8

jarsigner -verify ` -keystore my_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>

适用于 OpenJDK 11、openJDK 17 和 OpenJDK 21

jarsigner -verify ` -keystore my_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>

已知问题

  1. 我们不支持 Keytool 和 Jarsigner 的 EC 密钥。