我该如何使用 OpenSSL 和 key_mgmt_util 命令行工具将密钥安全传输到 CloudHSM 中?

4 分钟阅读
0

我有本地密钥,我希望使用 unWrapKey 命令与 key_mgmt_util 命令行工具将其导入至 AWS CloudHSM 中。但是,我无法导入或包装纯文本密钥。

解决方法

使用临时 AES 密钥加密有效负载密钥。使用密钥对中的公钥加密临时 AES。然后,将加密的有效负载密钥和加密的临时密钥串联到单个文件中。以加密格式将串联的文件发送至您的 CloudHSM,然后使用密钥对中的私有密钥进行解密。AES_KEY_WRAP 机制可解密临时 AES 密钥,并可以使用该密钥解密您的有效负载密钥。

创建以下密钥:

  • 有效负载 AES 或 RSA 密钥。此密钥为您导入并用于 CloudHSM 的密钥。
  • AES_KEY_WRAP 加密有效负载所需的临时 AES 密钥。最佳实践是使用 AES,因为它对于可加密的内容大小没有限制。
  • 用于安全包装和将这些密钥解包到 CloudHSM 中的 RSA 密钥对。

开始之前,请确保您拥有 OpenSSL 的修补版本,以允许进行信封包装。有关说明,请参阅我该如何修补 OpenSSL 以激活用于 CloudHSM CKM_RSA_AES_KEY_WRAP 机制?

创建、加密和导入本地密钥

1.    运行以下命令以创建有效负载、临时和 RSA 密钥。

**提示:**在它们自己的目录中创建这些密钥,以跟踪您的文件。

openssl rand -out payload_aes 32
openssl rand -out ephemeral_aes 32
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -out public.pem -pubout -outform PEM

2.    使用此命令将临时 AES 密钥的原始十六进制值输出到变量中。

EPHEMERAL_AES_HEX=$(hexdump -v -e '/1 "%02X"' < ephemeral_aes)

**注意:**确保您安装了 hexdump 实用程序,否则此命令会返回错误。有关如何安装 hexdump 实用程序,请参阅您的操作系统文档。

3.    使用 OpenSSL enc 命令以利用临时 AES 密钥包装有效负载。-id-aes256-wrap-pad 密码是符合 RFC 3394 的包装机制,它与 CKM_RSA_AES_KEY_WRAP 相一致。-iv 值由 RFC 5649(RFC 3394 的扩展)设置。

OPENSSL_V111 enc -id-aes256-wrap-pad -K $EPHEMERAL_AES_HEX -iv A65959A6 -in payload_aes -out payload_wrapped

4.    使用您在步骤 1 中创建的 RSA 密钥对中的公有密钥加密 AES 密钥。

OPENSSL_V111 pkeyutl -encrypt -in ephemeral_aes -out ephemeral_wrapped -pubin -inkey public.pem -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha1 -pkeyopt rsa_mgf1_md:sha1

5.    从本地计算机中,将加密有效负载密钥和临时 AES 密钥串联到名为 rsa_aes_wrapped 的单个文件中。

cat ephemeral_wrapped payload_wrapped > rsa_aes_wrapped

6.    从本地计算机将 RSA 私有密钥导入 CloudHSM 中。在 HSM 中创建持久性 AES 密钥,以使用 importPrivateKey 管理导入。

**注意:**将 user-nameuser-password 替换为您的 CloudHSM 用户名和密码。

**注意:**如果您在 HSM 上创建了 RSA 密钥对并使用 exportPubKey 导出了公有密钥,则您可以跳过步骤 6-9。

/opt/cloudhsm/bin/key_mgmt_util Cfm3Util singlecmd loginHSM -u CU -s user-name -p user-password  genSymKey -t 31 -s 32 -l aes256

警告:该命令可以在本地记录您的用户名和密码的详细信息。在传输密钥后,最佳实践是更改密码。 除了指定加密用户密码之外,您还可以编写 shell 脚本以避免在 shell 历史记录中记录密码。此 shell 脚本将接收 key_mgmt_util 的所有参数,并将它们发送到此命令。这允许您使用 shell 脚本来运行上面的命令以及下面的其他 key_mgmt_util 命令。

7.    您会收到类似如下内容的输出。记下 AES 密钥句柄—它用于导入私有 RSA 密钥。在此示例中,密钥句柄为 7。

Command: genSymKey  -t  31  -s  32  -l  aes256
        Cfm3GenerateSymmetricKey returned: 0x00 : HSM Return: SUCCESS
        Symmetric Key Created.  Key Handle: 7
        Cluster Error Status
        Node id 0 and err state 0x00000000 : HSM Return: SUCCESS

8.    导入私有密钥并将其包装到 HSM 中。使用您在步骤 6 中创建的持久性 AES 密钥保护导入的安全。 **注意:**将选项 -w 7 替换为您的密钥句柄。

/opt/cloudhsm/bin/key_mgmt_util Cfm3Util singlecmd loginHSM -u CU -s user-name -p user-password  importPrivateKey -l private -f private.pem -w 7

9.    您会收到类似如下内容的输出。记下已导入的 RSA 私有密钥句柄。在本示例中,导入的 RSA 私有密钥为 8

Cfm3WrapHostKey returned: 0x00 : HSM Return: SUCCESS
        Cfm3CreateUnwrapTemplate2 returned: 0x00 : HSM Return: SUCCESS
        Cfm3UnWrapKey returned: 0x00 : HSM Return: SUCCESS
        Private Key Imported.  Key Handle: 8
        Cluster Error Status
        Node id 0 and err state 0x00000000 : HSM Return: SUCCESS

10.    将导入的 RSA 私有密钥与 unWrapKey 命令结合使用,以将串联的有效负载密钥解包到 HSM 中。此示例将 -w 8 用作导入 RSA 私有密钥的密钥句柄。

**注意:**将 -w 8 替换为您的私有密钥句柄。

/opt/cloudhsm/bin/key_mgmt_util Cfm3Util singlecmd loginHSM -u CU -s user-name -p user-password  unWrapKey -f rsa_aes_wrapped -w 8 -m 7 -noheader -l secretkey -kc 4 -kt 31

注意:您必须使用 -kc 4 -kt 31 解包 AES 密钥,并使用 -kc 3 -kt 0 解包 RSA 私有密钥。有关使用 -m-kc-kt 参数的更多信息,请参阅 unWrapKey 示例

11.    您收到类似以下输出的有效负载 AES 密钥成功导入消息:

**注意:**在本示例中,新解包密钥的密钥句柄 10 可在 CloudHSM 中使用。

Cfm3CreateUnwrapTemplate2 returned: 0x00 : HSM Return: SUCCESS
        Cfm2UnWrapWithTemplate3 returned: 0x00 : HSM Return: SUCCESS
        Key Unwrapped.  Key Handle: 10
        Cluster Error Status
        Node id 0 and err state 0x00000000 : HSM Return: SUCCESS

请验证您已导入有效负载 AES 密钥

1.    使用包装密钥 -w 7 将有效负载 AES 密钥导出回磁盘中。将有效负载密钥句柄 10 替换为您自己的导入有效负载 AES 密钥值。

/opt/cloudhsm/bin/key_mgmt_util Cfm3Util singlecmd loginHSM -u CU -s user-name -p user-password exSymKey -k 10 -w 7 -out HSM.key

2.    运行此命令以将导入的有效负载密钥与 payload_aes 密钥相比较。

diff HSM.key payload_aes --report-identical-files

3.    如果 HSM.keypayload_aes 密钥是相同的,您将收到以下输出:

Files HSM.key and payload_aes are identical

导入 RSA 有效负载

1.    如果您想将 RSA 私有密钥解包到 HSM 中,请运行以下命令以将有效负载密钥更改为 RSA 私有密钥。

openssl genrsa -out payload_rsa.pem 2048
openssl rand -out ephemeral_aes 32
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -out public.pem -pubout -outform PEM

2.    使用 OpenSSL 从导入 RSA 有效负载所需的步骤部分中的步骤 1 创建的 RSA 密钥为 PKCS #1 格式。然而,key_mgmt_util 工具假设私有密钥的格式为 PKCS #8 DER。使用您常用的文本编辑器以纯文本形式查看密钥,以确认格式类似以下内容:

  • PKCS1 格式: -----BEGIN RSA PRIVATE KEY----- - PKCS8 格式:-----BEGIN PRIVATE KEY-----

3.    要将 payload_rsa.pem 密钥转换为 pkcs8 格式和 DER 编码,请运行此命令:

openssl pkcs8 -topk8 -inform PEM -outform DER -in payload_rsa.pem -out payload_rsa_pkcs8.der -nocrypt

4.    按照创建、加密和导入本地密钥部分中的步骤 2-9。

**注意:**将 payload_aes 替换为 payload_rsa_pkcs8.der

5.    运行此命令以将有效负载 RSA 私有密钥解包到 CloudHSM 中,并记下输出密钥句柄:

/opt/cloudhsm/bin/key_mgmt_util singlecmd loginHSM -u CU -s user-name -p user-password unWrapKey -f rsa_aes_wrapped -kc 3 -kt 0 -w 8 -l private_key -m 7 -noheader

**注意:**您必须使用 -kc 4 -kt 31 解包 AES 密钥,并使用 -kc 3 -kt 0 解包 RSA 私有密钥。

现在,您已将有效负载 RSA 密钥解包到 HSM 中。

请验证您已导入有效负载 RSA 私有密钥

1.    使用您之前创建的包装密钥将有效负载 RSA 私有密钥导出回磁盘中。将有效负载密钥句柄 25 替换为您自己的导入有效负载 RSA 私有密钥值。

/opt/cloudhsm/bin/key_mgmt_util Cfm3Util singlecmd loginHSM -u CU -s user-name -p user-password exportPrivateKey -k 25 -w 7 -out HSM_rsa_private.key

2.    运行此命令以将 payload_rsa 密钥转换为 PKCS #8 格式,而不是转换为 DER。

openssl pkcs8 -topk8 -inform PEM -outform PEM -in payload_rsa.pem -out payload_rsa_pkcs8.pem -nocrypt

3.    运行此命令以将导入的有效负载密钥与 payload_rsa 密钥进行比较。

diff HSM_rsa_private.key payload_rsa_pkcs8.pem --report-identical-files

4.    如果 HSM_rsa_private.keypayload_rsa_pkcs8.pem 密钥相同,您将收到以下输出:

Files HSM_rsa_private.key and payload_rsa_pkcs8.pem are identical

相关信息

支持的 PKCS #11 机制

OpenSSL

Oasis 要求与 PKCS#11 规范

RFC 3394

RFC 5649

AWS 官方
AWS 官方已更新 2 年前