使 EOA 私钥与 AWS KMS 兼容 数据库博客
EOA 私钥与 AWS KMS 的兼容性
主要收获
在这篇文章中,我们深入探讨了数字资产如加密货币和非同质化代币管理所需的安全性,尤其是如何将外部拥有的账户EOA私钥与 AWS KMS 进行兼容。文章内容包括: 以太坊账户类型的概述 利用 AWS KMS 管理非托管区块链钱包私钥的优势 椭圆曲线私钥的存储及 PKCS #8 和 ASN1 标准 如何将私钥转换为 PKCS #8 格式,以便与 AWS KMS 兼容
本文针对那些希望更好地管理数字资产私钥的读者,提供了实用的步骤和最佳实践。
在创建数字资产钱包时,用户面临一个重要决定:是自行管理钱包,还是将此责任委托给受信任的第三方?非托管钱包即用户自己管理钱包因其给予用户对数字资产的完全控制而受到欢迎。然而,同时也存在不容小觑的风险:如果管理不善,数字资产可能会面临丢失的风险。
希望不承担管理责任的用户可以选择托管钱包,这种方式由第三方代为管理。然而,托管钱包同样面临独特的风险,如保管者的安全短板、破产和内部威胁,这些都可能导致数字资产的损失。尽管非托管钱包也存在风险,比如必须额外维护私钥的安全,但保持对钱包的完全控制则可以有效降低因第三方管理而带来的风险。
以太坊账户类型
以太坊有两种账户类型:外部拥有账户EOA和合约账户。EOA 可以通过私钥控制,而合约账户则与智能合约关联,且由代码控制。
EOAs 允许用户自己签名并发起交易,而智能合约账户则始终需要外部账户来触发代码。
通常,像 MetaMask 这样的 EOA 钱包只关联一个私钥。该私钥对应的公钥决定了钱包的公用地址。这意味着,获得私钥的任何人都能对钱包内所有资产拥有完全控制权没有授权系统。因此,EOA 钱包常常成为恶意攻击者的目标,因为获取私钥即可无限制地提取该钱包内所有资产。此外,EOA 缺乏有效的密钥恢复机制,主流的恢复方式是使用由 12 个单词组成的秘密恢复短语 若丢失,则无法重建钱包;若攻击者获得该列表,则整个钱包将面临被抽空的风险。
智能合约钱包如 Gnosis Safe则更为复杂,通常用于大型去中心化自治组织DAO的资金管理。智能合约钱包通常采用多签方案,需要多个 EOA 签名以授权和发起区块链交易,提供额外的安全层,防止攻击者通过单一私钥的泄露导致资金的全部损失。
使用专用服务降低运营风险
为解决与私钥或 EOA 钱包管理相关的运营挑战,使用在线硬件安全模块HSM等专用解决方案或完全管理的服务如 AWS KMS会显得非常有益。
通过使用 AWS KMS,这种经过FIPS140 Level 3 验证的完全管理解决方案,可以有效降低运营钥匙管理风险。
一旦密钥被导入,密钥只存在于 AWS KMS 和原始 EOA 来源中,KMS 密钥实例无法导出。AWS KMS 会在设计用于99999999999 耐久性的系统中存储多个加密版本的密钥副本,更多信息请参见 可扩展性、耐久性和高可用性。关于允许的密钥操作, 请参见 AWS KMS 常见问题。
如需频繁进行密钥的编程访问,AWS KMS 则非常适合这些用例。这得益于其与 AWS 身份和访问管理IAM的完全集成,以进行身份验证和授权管理。此外,KMS API 支持对导入的私钥执行所有必需的加密操作,例如创建数字签名。
使用此类解决方案时需要考虑成本。每月管理的 AWS KMS 导入密钥费用为 1,与使用量无关。对于需要管理大量密钥的用例,基于 AWS Nitro Enclaves 的密钥管理解决方案可能更具成本效益。有关 Nitro Enclaves 的密钥管理的更多信息,请参见 AWS Nitro Enclaves 进行安全区块链密钥管理。
将密钥导入到 AWS KMS 或 HSM 等完全管理的专用服务并非完全没有风险。对于 AWS KMS,客户必须保持适当的 IAM 权限,以允许对导入密钥的访问,同时 AWS 则负责其数据中心的物理安全。这种责任分离被称为 共享责任模型。
椭圆曲线私钥表示
椭圆曲线私钥是位于曲线域大小内的随机整数,通常为 256 位或 32 字节大小。例如,secp256k1 曲线的域参数可在 SEC 2 推荐的椭圆曲线域参数 的第 9 页第 24 节找到。
椭圆曲线公钥则为 (x y) 两个整数坐标的组合,均为 256 位大小。由于椭圆曲线的特殊对称性,公钥可以被压缩为 256 位坐标 1 位,后者指示该点位于曲线的上半部分或下半部分,具体可参考以下椭圆曲线图示。
在区块链领域,或更具体地说,在以太坊中,公钥 y 值的奇偶性可为 0 或 1。有关更多信息,请参见 EIP155。
飞鸟加速器最新版下载兼容 EVM 的 EOA 钱包使用原始私钥32 字节,未附加任何元数据;因此,椭圆曲线参数的名称固定为 secp256k1。为了导出和传输私钥,32 字节通常会转换为 64 字符的十六进制字符串,因为不存在额外的转义需求。这样,十六进制字符串就可以使用 JSON 语法直接存储和分发。
PKCS #8 和 ASN1 标准的私钥表示
如 AWS KMS 等完全管理的密钥管理服务使用的是 公钥密码标准PKCS进行密钥管理操作。

在密钥的导入和导出过程中,AWS KMS 依赖 PKCS #8 标准,该标准定义了私钥信息明文和加密形式及一组属性的语法。
PKCS #8 使用的是 抽象语法表示法ASN1标准。ASN1 是全球公认的接口描述语言,用于定义可以跨平台序列化和反序列化的数据结构。
正如互联网工程任务组IETF对于 椭圆曲线私钥结构 中提到的,“本文件中定义的结构允许生成私钥和公钥的实体分发密钥对及其关联的域参数。”该结构的版本 1 如下所示:
ECPrivateKey = SEQUENCE { version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1) privateKey OCTET STRING parameters [0] ECParameters {{ NamedCurve }} OPTIONAL publicKey [1] BIT STRING OPTIONAL }
它包含以下字段: version 参考所使用的椭圆曲线私钥结构的语法版本。到目前为止,相关的 IETF 标准为版本 1。 privateKey 是无符号整数的字节序列表示形式的私钥。 parameters 是一个可选字段,指定椭圆曲线域参数,例如以太坊或比特币兼容私钥的曲线名称 secp256k1。 publicKey 是一个可选字段,可用于存储与私钥相关联的公钥。由于公钥总是可以根据私钥重新计算,因此其存在也提供了方便。
ASN1 结构可以使用多种高级编程语言进行解析和创建,例如使用 asn1tools 包的 Python 或通过 OpenSSL 使用 [asn1parse](https//wwwopensslorg/docs/man111/man1/opensslasn1parsehtml) 或 ASN1generatev3 指令。
声明
请注意,私钥管理伴随着巨大的风险。本文展示的所有命令和示例仅用于技术演示,不应视为生产环境准备。此外,您有责任在 AWS 之外保持密钥管理的安全性、可用性和耐久性。
将原始私钥转换为有效的 PKCS #8 结构
某些 Web3 框架和 SDK例如 Python 的 web3py 或 EOA 钱包解决方案如 MetaMask中使用的私钥作为 32 字节整数存储,而没有任何关联的域参数。
要将这些整数转换为有效的 PKCS #8/ASN1 格式,您需要指定与这些私钥关联的域参数,例如椭圆曲线。默认情况下,以太坊或 EVM 兼容链依赖于 secp256k1 椭圆曲线。
请按照以下步骤创建一个临时私钥,类似于非托管加密钱包管理其密钥的方式,并将其转换为 PKCS #8 格式,以便能够与 AWS KMS 兼容:
生成一个临时 secp256k1 私钥,打印出其公钥以便后续比较,并提取原始私钥: bash openssl ecparam name secp256k1 genkey out privatekeypem openssl ec in privatekeypem pubout out publickeypem cat privatekeypem openssl ec text noout grep priv A 3 tail n 2 tr d n[space] sed s/00// 结果将是一个以十六进制字符串编码的原始私钥,格式与非托管 EOA 钱包存储的密钥相似。
使用 openssl 命令重新组装 ASN1 结构,并按 AWS KMS 的要求以 PKCS #8 格式存储新密钥: bash openssl pkcs8 topk8 outform DER nocrypt inform DER in lt(echo 302e0201010420 lt privatekeygt a00706052b8104000a xxd r p) out privatekeyreassembledpkcs8 在此示例中,我们将密钥的十六进制字符串表示与序列化的 ASN1 参数结合:
302e0201010420 定义了 ASN1 序列的起始部分,并指定了不包含公钥的总长度。
a00706052b8104000a 定义了以 OID 12132010 编码的 namedcurve 参数,对应 secp256k1。OID 可视为接受的标准的全球注册表,如 加密算法。有关 ASN1 及用于重新组装密钥结构的值的更多详细信息,请参见 Stackoverflow 1 或 Stackoverflow 2。
如前文所述,ASN1 结构也可以在更高级的编程语言如 Python中组合和序列化,如以下代码片段所示。为避免添加额外的外部依赖项,我们使用了预定义的值。
inform DER 和 outform DER 标志指示我们正在按照 ASN1 描述的二进制格式导入和导出明文密钥。
另外,如果要从转换后的私钥计算公钥并与初始保存的公钥进行比较,请按照以下附加步骤操作:
解析重建的私钥并打印出公钥: bash openssl ec in privatekeyreassembledpkcs8 pubout outform PEM out publickeyreassembledpem
比较初始和重建的公钥,例如使用 diff 确保它们相等: bash diff publickeypem publickeyreassembledpem
使密钥兼容 PKCS #8
您可以从以下 GitHub 仓库 下载一个 shell 脚本,以自动将表示为 64 字符十六进制字符串的 secp256k1 私钥转换为有效的 PKCS #8 结构以 DER 编码。直接下载脚本而不克隆整个仓库需要先通过 chmod x scriptname 添加运行权限:
bash/reassemblepkcs8sh lt privatekeygt
如果成功,reassemblepkcs8sh 脚本将把 DER 编码的私钥写入本地文件夹。
现在,您可以使用这些文件将密钥导入到 AWS KMS。有关如何将重新组装的私钥导入 AWS KMS 的说明,请参见 AWS KMS 密钥材料导入。高层步骤如下:
创建一个 KMS 密钥。下载加密包装密钥。使用包装密钥加密要导入的密钥材料。导入新密钥。有关自动化密钥导入过程的更多信息,请参见 将以太坊私钥导入 AWS KMS。
结论
在此文中,我们提供了不同钱包类型的简要介绍,并讨论了一些优缺点。我们还解释了为什么密钥管理总体上是一个挑战,以及为什么将与密钥管理相关的任务外包给专用服务具有潜在的好处。此外,我们还解释了私钥和公钥如何使用 PKCS #8 和 ASN1 标准存储,以及不同格式在不同应用场景中的优势,比如网络传输。最后,我们演示了如何让非托管钱包使用的原始椭圆曲线私钥与 AWS KMS 兼容。
您可以利用本文提供的指示创建自己的私钥区块链密钥,并将其转换为 PKCS #8。使用 将以太坊私钥导入 AWS KMS 中描述的机制安全导入 AWS KMS 中的密钥。在最后一步,创建并签署以太坊兼容的交易,具体步骤请参见 如何使用 AWS KMS 签署以太坊 EIP1559 交易。
作者简介
DavidPaul Dornseifer 是 AWS 全球专家组织的