使用AWS re:Post即您表示您同意 AWS re:Post 使用条款

如何使用 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,因为可加密的内容没有大小限制。
  • RSA 密钥对,用于将密钥安全地封装和解包到 CloudHSM 中。

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

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

要创建、加密和导入本地密钥,请完成下面的步骤:

  1. 运行以下命令来创建有效负载、临时和 RSA 密钥:
    提示: 要跟踪您的文件,请在它们自己的目录中创建这些密钥。

    openssl rand -out payload_aes 32openssl 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,则上述命令会返回错误。有关如何安装 hexdump 实用程序的说明,请参阅操作系统(OS)文档。

  3. 运行 OpenSSL enc 命令来使用临时 AES 密钥封装有效负载:

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

    注意: -id-aes256-wrap-pad 密码是符合 RFC 3394 的封装机制,与 CKM_RSA_AES_KEY_WRAP 一致。RFC 3394 扩展 RFC 5649 设置 -iv 值。有关更多信息,请参阅 Datatracker 网站上的 Advanced Encryption Standard (AES) key wrap with padding algorithmAdvanced Encryption Standard (AES) key wrap algorithm

  4. 使用 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
    

    **注意:**如果使用 exportPubKey 在 HSM 上创建 RSA 密钥对并导出了公有密钥,请继续执行步骤 10。

  6. 将 RSA 私有密钥从本地计算机导入 CloudHSM。要管理导入,请使用 importPrivateKey 在 HSM 中创建永久 AES 密钥。将 user-nameuser-password 替换为您的 CloudHSM 用户名和密码:

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

    警告: 上述命令可以在本地记录您的用户名和密码的详细信息。传输密钥后,最好更改密码。请勿指定加密用户密码。相反,编写一个 shell 脚本,以便密码不记录在 shell 历史记录中。shell 脚本接收 key_mgmt_util 的所有参数,并将它们发送到此命令。

  7. 请注意用于导入 RSA 私有密钥的 AES 密钥句柄。在以下示例输出中,密钥句柄为 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 中。使用永久 AES 密钥来保护导入。将 -w 7 替换为您的密钥手柄:

    /opt/cloudhsm/bin/key_mgmt_util singlecmd 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 替换为您的私有密钥句柄:

/opt/cloudhsm/bin/key_mgmt_util singlecmd -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 示例

您将成功导入有效负载 AES 密钥,其类似于以下输出:

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

注意: 在前面的示例中,可以在 CloudHSM 中使用新解封密钥的密钥句柄 10

验证您是否导入了有效负载 AES 密钥

要验证您是否导入了有效负载 AES 密钥,请完成下面的步骤:

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

    /opt/cloudhsm/bin/key_mgmt_util 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
    

如果 HSM.keypayload_aes 密钥相同,则将收到以下输出:

Files HSM.key and payload_aes are identical

导入 RSA 有效负载

要导入有效负载,请完成下面的步骤:

  1. 要将 RSA 私有密钥解压缩到 HSM 中,请运行以下命令来将有效负载密钥更改为 RSA 私有密钥:

    openssl genrsa -out payload_rsa.pem 2048openssl rand -out ephemeral_aes 32
    openssl genrsa -out private.pem 2048
    openssl rsa -in private.pem -out public.pem -pubout -outform PEM
    
  2. 使用纯文本编辑器检查 RSA 密钥的格式:

    PKCS1 format: -----BEGIN RSA PRIVATE KEY----- - PKCS8 format: -----BEGIN PRIVATE KEY-----

    注意: RSA 密钥采用 PKCS #1 格式。但是,key_mgmt_util tool 假定私有密钥采用 PKCS #8 DER 格式。

  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 私有密钥

要验证您是否导入了有效负载 RSA 私有密钥,请完成以下步骤:

  1. 使用密钥封装将有效负载 RSA 私有密钥导出回磁盘。将有效负载密钥句柄 25 替换为您的有效负载 RSA 私有密钥值:

    /opt/cloudhsm/bin/key_mgmt_util 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 格式:

    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
    

如果 HSM_rsa_private.keypayload_rsa_pkcs8.pem 密钥相同,则会收到以下输出:

Files HSM_rsa_private.key and payload_rsa_pkcs8.pem are identical

相关信息

Supported mechanisms

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