如何将非对称密钥从 CloudHSM 迁移到 AWS KMS 安全博客
  • 18

从 CloudHSM 迁移非对称密钥到 AWS KMS 的方法

作者 Mani Manasa Mylavarapu Kevin Lee 和 Patrick Palmer日期 2024年2月6日类别 高级 (300)标签 AWS CloudHSM AWS 密钥管理服务 (KMS) AWS KMS CloudHSM 安全博客

文章要点

新功能介绍 2023年6月,AWS KMS 引入了支持导入非对称密钥材料的功能,包括 RSA 和椭圆曲线密码学 (ECC) 私钥。迁移的好处 将非对称密钥从 CloudHSM 迁移至 AWS KMS 后,你可以简化密钥管理策略,同时享受 AWS KMS 的强大授权控制。解决方案概览 解决方案包括下载 AWS KMS 的填充密钥,使用 CloudHSM 命令行接口导入该密钥,再通过 AWS KMS 导入包裹后的私钥。关键步骤 包括创建 KMS 密钥、下载包裹公钥、导入包裹密钥、包裹私钥以及导入至 AWS KMS。

2023年6月,亚马逊网络服务AWS 为 AWS 密钥管理服务AWS KMS 引入了一个新功能:现可将非对称密钥材料例如 RSA 或椭圆曲线算法ECC的私钥导入 AWS KMS。这意味着可以将外部管理的非对称密钥迁移到 AWS KMS,包括混合环境、多云环境以及 AWS CloudHSM,让它们通过 AWS KMS 可用。结合 AWS KMS HSM 获得 FIPS 1402 安全级别 3 的公告,可以确保你的密钥在符合美国国家标准与技术研究院NIST规定的密码学标准的方式中被安全使用。

在本文中,我们将展示如何将非对称密钥从 CloudHSM 迁移到 AWS KMS。这将帮助你简化密钥管理策略,并充分利用 AWS KMS 密钥策略的强大授权控制。

将密钥材料导入 AWS KMS 的好处

我们通常推荐使用原生的 KMS 密钥,因为其在安全性、耐用性和可用性上比其他密钥存储选项更具优势。AWS KMS 的 FIPS 验证硬件安全模块HSM 生成 KMS 密钥的材料,且这些材料在离开 HSM 之前始终是加密的。涉及 KMS 密钥的操作例如解密数据密钥或数字签名必须在 HSM 内部完成。

然而,根据组织的需求,你可能需要从外部带入自己的密钥BYOK。导入自己的密钥让你直接控制密钥的生成、生命周期管理与耐用性。此外,你可以完全控制导入密钥的可用性,可以设置过期时间,或随时删除并重新导入密钥。通过保持密钥的原始版本,你可以对导入的密钥的耐用性进行更大控制。如果你需要在 AWS 外部生成和存储密钥的副本,这些额外的控制可以帮助你满足合规要求。

解决方案概览

总体而言,我们的解决方案包括以下步骤:

在 AWS KMS 创建没有密钥材料的 KMS 密钥。从 AWS KMS 下载填充公钥和导入令牌。将 AWS KMS 提供的包裹密钥导入 CloudHSM。使用 AWS KMS 导入的包裹公钥在 CloudHSM 内包裹私钥。将包裹后的私钥导入 AWS KMS。

在这篇文章的操作示例中,你将从一个 CloudHSM 集群中导入 256 位 ECC 私钥NIST P256,该密钥用于签名。导入非对称密钥时,只需要导入私钥。导入时无需提供公钥,因为 AWS KMS 在导入私钥后可以生成和检索对应的公钥。

前提条件

为顺利进行接下来的操作,请确保满足以下前提条件:

如何将非对称密钥从 CloudHSM 迁移到 AWS KMS 安全博客有一个活跃的 CloudHSM 集群,至少有一个处于活跃状态的 HSM,以及有效的 加密用户 凭证。一台已安装并配置了 CloudHSM 客户端 SDK 5 的 Amazon Elastic Compute Cloud (Amazon EC2) 实例,以连接到 CloudHSM 集群。有关如何配置和连接客户端实例的说明,请参见 开始使用 AWS CloudHSM。在你的 EC2 实例上安装了 OpenSSL建议使用 300 版本或更新版本。

步骤 1 在 AWS KMS 中创建没有密钥材料的 KMS 密钥

第一步是创建一个新的 KMS 密钥。你可以通过 AWS KMS 控制台、AWS CLI 或运行 CreateKey API 操作来完成。

创建密钥时,请注意以下指导:

将密钥材料来源设置为 External,以便不会为此新密钥创建密钥材料。根据 NIST SP 80057 和密码学最佳实践,通常建议将单个密钥用于单一目的例如,如果你将 RSA 密钥用于加密,则不应同时将该密钥用于签名。选择最适合你用例的密钥用途。确保 密钥规格 与要从 CloudHSM 导入的密钥的算法规格相匹配。如果希望在多个 AWS 区域使用该密钥例如,为了避免跨区域访问密钥的需要,请考虑使用 多区域密钥。使用 AWS CLI 创建 KMS 密钥

运行以下命令:

bashaws kms createkey origin EXTERNAL keyspec ECCNISTP256 keyusage SIGNVERIFY

步骤 2 从 AWS KMS 下载包裹公钥和导入令牌

创建密钥后,下载包裹密钥和导入令牌。

所选的包裹密钥规格和算法取决于你要导入的密钥。AWS KMS 支持 多个标准 RSA 包裹算法和两步混合包裹算法。 CloudHSM 同样支持这两种包裹算法。

通常情况下,选择 RSA 包裹算法 (RSAESOAEPSHA),密钥规格为 RSA4096 应足够用于包裹 ECC 私钥,因为它可以完全包裹密钥材料。然而,在导入 RSA 私钥时,由于其较大的密钥大小,你将需要使用两步混合包裹算法 (RSAAESKEYWRAPSHA)。整体流程与此处所示相同,但两步混合包裹算法要求你使用自己生成的高级加密标准AES对称密钥加密密钥材料,然后使用 RSA 公共包裹密钥加密 AES 对称密钥。此外,在选择包裹算法时,你还需在 SHA1 和 SHA256 哈希算法之间做出选择。我们建议在条件允许的情况下优先使用 SHA256 哈希算法。

请注意,每组包裹公钥和导入令牌的有效期为 24 小时。如果你在下载后 24 小时内没有使用该组导入密钥材料,则必须重新下载一组。

从 AWS KMS 下载包裹公钥和导入令牌运行以下命令。确保将 ltKMS KeyIDgt 替换为你在上一步创建的 KMS 密钥的密钥 ID。密钥 ID 是密钥 ARN 中最后一部分,格式为 key/例如,arnawskmsuseast1key/。importTokenb64 代表包裹令牌,WrappingPublicKeyb64 代表导入令牌。

bashaws kms getparametersforimport keyid ltKMS KeyIDgt wrappingalgorithm RSAESOAEPSHA256 wrappingkeyspec RSA4096 query [ImportToken PublicKey] output text awk {print 1 gt ImportTokenb64 print 2 gt WrappingPublicKeyb64}

解码 base64 编码。

bashopenssl enc d base64 A in WrappingPublicKeyb64 out WrappingPublicKeybin

将包裹公钥从 DER 格式转换为 PEM 格式CloudHSM 命令行接口CLI 中的密钥导入 pem 命令要求公钥为 PEM 格式。AWS KMS 输出的公钥为 DER 格式,因此需要将包裹公钥转换为 PEM 格式。要将公钥转换为 PEM 格式,请运行以下命令:

bashopenssl rsa pubin in WrappingPublicKeybin inform DER outform PEM out WrappingPublicKeypem

步骤 3 将 AWS KMS 提供的包裹密钥导入 CloudHSM

现在你已经创建了 KMS 密钥并做好了导入准备,通往 CloudHSM 导入密钥。

导入包裹密钥登录到安装了 CloudHSM CLI 的 EC2 实例,并运行以下命令以交互模式使用它:

bash/opt/cloudhsm/bin/cloudhsmcli interactive

使用你的加密用户凭证进行登录。请替换 ltYourUserNamegt 为你的信息,并在提示时输入密码。

bashlogin username ltYourUserNamegt role cryptouser

导入包裹密钥并设置属性以允许此密钥用于包裹其他密钥。

bashkey import pem path /WrappingPublicKeypem label ltkmswrappingkeygt keytypeclass rsapublic attributes wrap=true

你应该会看到类似于以下的输出:

json{ errorcode 0 data { key { keyreference 0x00000000002800c2 keyinfo { keyowners [ { username ltYourUserNamegt keycoverage full } ] sharedusers [] clustercoverage full } attributes { keytype rsa label ltkmswrappingkeygt id 0x checkvalue 0x5efd07 class publickey encrypt false decrypt false token true alwayssensitive false derive false destroyable true extractable true local false modifiable true neverextractable false private true sensitive false sign false trusted false unwrap false verify false wrap true wrapwithtrusted false keylengthbytes 1024 publicexponent 0x010001 modulus 0xd7683010 b6fc9df07 modulussizebits 4096 } } message Successfully imported key }}

从输出中记录密钥标签的值本文例中为 ltkmswrappingkeygt,因为你在下一个步骤中将需要用到它。

步骤 4 使用 AWS KMS 导入的包裹公钥在 CloudHSM 中包裹私钥

现在你已经将包裹密钥导入到 CloudHSM 中,你可以使用该包裹密钥将要导入 AWS KMS 的私钥进行包裹。

重要 只有密钥的拥有者即创建密钥的加密用户才能包裹密钥。此外,要包裹的密钥必须具有可提取属性设置为 true。

包裹私钥使用 CloudHSM CLI 中的 key wrap 命令包裹存储在 CloudHSM 中的私钥。确保用自己的信息替换以下占位符值:rsaoaep 指定包裹算法。payloadfilter 用于定义要包裹出 HSM 的密钥。你可以使用密钥引用例如,keyreference=0x00000000002800c2或引用密钥属性,如密钥标签。在我们的例子中,使用了密钥标签 ecprivimporttokms。wrappingfilter 用于定义你将用于包裹有效负载密钥的密钥。这应是你之前从 AWS KMS 导入并在步骤 33 中标记为 kmswrappingkey 的包裹密钥。hashfunction 定义作为 OAEP 加密的一部分使用的哈希函数。这应该与从 AWS KMS 获取导入参数时指定的包裹算法相匹配。在我们的例子中,应为 SHA256,因为我们之前选择了 RSAESOAEPSHA256 作为包裹算法。mgf 定义作为 OAEP 加密的一部分使用的屏蔽生成函数。屏蔽哈希函数必须与签名机制哈希函数匹配,在此例中为 SHA256。path 定义保存包裹密钥数据的二进制文件的路径。在本示例中,我们命名为 EncryptedECCP256KeyMaterialbin,但你可以指定不同的名称。

bashkey wrap rsaoaep payloadfilter attrlabel=ecprivimporttokms wrappingfilter attrlabel=kmswrappingkey hashfunction sha256 mgf mgf1sha256 path EncryptedECCP256KeyMaterialbin

可选导出公钥你还可以使用 CloudHSM CLI 导出私钥的公钥。后续需要使用此密钥进行测试。确保将占位符值 ltecprivimporttokmsgt 和 ltKeyNamepemgt 替换为你自己的信息。

bashkey generatefile encoding pem path ltKeyNamepemgt filter attrlabel=ltecprivimporttokmsgt

魔戒机场

步骤 5 将包裹私钥导入 AWS KMS

现在你已经从 CloudHSM 包裹了私钥,可以将其导入 AWS KMS。

请注意,你有选择为导入的密钥设置过期时间。过期时间一旦到期,AWS KMS 会自动删除你的导入密钥。

将包裹私钥导入 AWS KMS如果你一直在使用 CLI 或 API,导入令牌是 base64 编码的,你必须将令牌从 base64 解码为二进制格式。你可以使用 OpenSSL 完成此操作。

bashopenssl enc d base64 A in ImportTokenb64 out ImportTokenbin

运行以下命令以导入包裹私钥。确保将 ltKMS KeyIDgt 替换为你在步骤 1 中创建的 KMS 密钥的密钥 ID。

bashaws kms importkeymaterial keyid encryptedkeymaterial fileb//EncryptedECCP256KeyMaterialbin importtoken fileb//ImportTokenbin expirationmodel