使 EOA 私钥与 Amazon KMS 兼容
那些选择拥有数字资产(例如加密货币或不可替代代币(NFT))所有权的人在创建钱包时面临着一个关键的决定:他们是选择管理自己的钱包还是将该责任委托给可信的第三方?用户可以管理自己钱包的非托管钱包解决方案很受欢迎,因为它们允许用户对自己的数字资产钱包拥有完全的控制权和所有权。或者,那些不希望承担管理自己钱包责任的人可以求助于托管钱包提供商,即代表用户管理钱包的第三方。但是,托管钱包具有与之相关的独特风险,包括但不限于托管人的安全缺陷、破产以及在托管钱包情况下可能导致资金损失的内部威胁。
尽管非托管钱包有其自身的一系列风险,例如维护自己钱包安全的责任增加,但保持对钱包的完全控制是使自己免受第三方风险影响的一种机制。
在这篇文章中,我们讨论了以下主题:
- 以太坊账户类型的高级介绍
- 为何使用 Amazon Key Management Service (Amazon KMS) 等完全托管的服务来管理与非托管区块链钱包相关的私钥可能有益
- 椭圆曲线私钥是如何存储的,以及公钥密码学标准 8 (PKCS #8) 和抽象语法表示法一 (ASN1.) 标准
- 如何将私钥转换为 PKCS #8,从而使其与 Amazon KMS 兼容
以太坊账户类型
以太坊有两种账户类型:可以由私钥控制的外部账户(EOA)和合约账户,后者与智能合约关联并由代码控制。
尽管 EOA 可以自行签署和发起交易,但智能合约账户不能,也总是需要外部账户才能触发代码。
通常,诸如 MetaMask 之类的 EOA 钱包只有一个关联的私钥。私钥的相应公钥决定了钱包的公共地址。
因此,EOA 的设置方式通常是任何有权访问私钥的人都可以完全控制该钱包中的所有资产(无授权系统)。出于这个原因,恶意方经常将 EOA 钱包作为目标,因为访问该钱包的私钥使攻击者能够无限地耗尽钱包中的所有资产。此外,EOA 缺乏有效的密钥恢复机制和授权管理。如今,恢复密钥的主要方法是使用由 12 个字组成的秘密恢复短语。如果列表丢失,则无法重新创建钱包。如果攻击者获得访问该列表的权限,则整个钱包可能会被耗尽。
诸如 Gnosis Safe 之类的智能合约钱包更为复杂,通常与大型去中心化自治组织(DAO)的资金库等用例有关。智能合约钱包通常使用多重签名方案,其中需要多个 EOA 签名才能授权和启动区块链交易。这提供了额外的安全层,攻击者必须绕过这些安全层才能耗尽钱包,从而防止泄露一个私钥导致资金完全损失。
使用专门构建的服务降低运营风险
为了解决一些与私钥或 EOA 钱包管理相关的运营挑战,使用专门构建的解决方案(例如在线 HSM)或完全托管的服务(如 Amazon KMS)可能会有所帮助。
使用 Amazon KMS 作为完全托管的解决方案(也经过了 FIPS-140 3 级验证)有助于降低运营密钥管理风险。
导入后,密钥仅存在于 Amazon KMS 和原始 EOA 源中,无法导出 KMS 密钥实例。Amazon KMS 将密钥的加密版本的多个副本存储在设计为耐久性达到 99.9999999% 的系统中。有关更多信息,请参阅可扩展性、耐久性和高可用性。有关允许的密钥操作的更多信息,请参阅亚马逊云科技密钥管理服务常见问题解答。
Amazon KMS 等服务非常适合需要频繁以编程方式访问密钥的用例。这是由于与 Amazon Identity and Access Management (IAM) 进行了全面集成,用于身份验证和授权管理。此外,KMS API 支持对导入的私钥进行所有必需的加密操作,例如创建数字签名。
还需要考虑这样的解决方案的成本。由 Amazon KMS 管理的导入密钥每月收费 1 美元,与使用量无关。对于必须管理大量密钥的用例,基于亚马逊云科技 Nitro Enclaves 的密钥管理解决方案可以更具成本效益。有关用于密钥管理的 Nitro Enclaves 的更多信息,请参阅用于安全区块链密钥管理的亚马逊云科技 Nitro Enclaves。
将密钥导入 HSM 或 Amazon KMS 等完全托管的专用服务并非完全没有风险。对于 Amazon KMS,客户有责任维护相应的 IAM 权限,以授予对导入密钥的访问权限,同时亚马逊云科技在其数据中心实施物理安全。这种责任分工也被称为分担责任模式。
椭圆曲线私钥表示法
椭圆曲线私钥是曲线字段大小内的随机整数,通常为 256 位或 32 字节。例如,SEC 2:推荐的椭圆曲线域参数第 2.4 节第 9 页中列出了 secp256k1 曲线的曲线场参数。
另一方面,椭圆曲线公钥是成对的整数坐标(x,y),位于曲线上,每个坐标大小为 256 位。由于椭圆曲线的特殊对称特性,公钥可以压缩为 256 位坐标 + 1 位,表示该点位于曲线的上部还是下部,如以下椭圆曲线图所示。
在区块链世界中,尤其是在以太坊中,相应的参数是 y 值的平价,可以是 0 或 1。有关其他信息,请参阅 EIP-155。
与以太坊虚拟机(EVM)兼容的 EOA 钱包使用原始私钥(32 字节),不关联任何元数据;因此,诸如名称之类的椭圆曲线参数固定为 secp256k1。对于私钥的导出和传输,由于没有额外的转义要求,32 字节通常会转换为 64 个字符的十六进制字符串。因此,例如,可以使用 JSON 语法直接存储和分发十六进制字符串。
PKCS #8 和 ASN.1 私钥表示标准
Amazon KMS 等完全托管的密钥管理服务使用公钥加密标准 (PKCS) 进行密钥管理操作。
对于密钥导入和导出,Amazon KMS 依赖于 PKCS #8 标准,该标准定义了私钥信息的语法,例如私钥本身(纯文本和加密)和一组属性。
PKCS #8 使用抽象语法表示法一 (ASN.1) 标准。ASN.1 是一种全球认可的标准接口描述语言,用于定义可通过跨平台方式序列化和反序列化的数据结构。
正如互联网工程任务组(IETF)关于椭圆曲线私钥结构的评论请求(RFC)中指出的那样,"本文档中定义的结构允许生成私钥和公钥的实体分配密钥对和相关的域参数。"该结构的版本 1 如下所示:
它由以下字段组成:
version
引用了用于椭圆曲线私钥结构的语法版本。在撰写本文时,相关的 IETF 标准是版本 1。privateKey
是私钥无符号整数的字节序列表示形式。parameters
是一个可选字段,用于指定椭圆曲线域参数,例如曲线名称,例如与以太坊或比特币兼容secp256k1
的私钥。publicKey
是一个可选字段,可用于存储私钥的关联公钥。由于公钥始终可以从私钥中重新计算,因此它的存在是为了方便消费者。
可以使用许多高级编程语言解析和创建 ASN.1 结构,例如使用 asn1tools 包的 Python 或通过 OpenSSL 使用 asn1parse
或 ASN1_Generate_v3 指令进行解析和创建。
免责声明
请注意,私钥管理存在很大的风险。本文中显示的所有命令和示例均用于技术演示,不被认为可以投入生产。此外,您还负责亚马逊云科技之外的密钥管理、安全性、可用性和耐久性。
将原始私钥转换为有效的 PKCS #8 结构
某些 Web3 框架和软件开发工具包(例如 Python web3py 或 MetaMask 等 EOA 钱包解决方案)中使用的私钥存储为 32 字节整数,没有任何关联的域名参数。
要将这些整数转换为有效的 PKCS #8 /ASN.1 格式,您需要指定域参数,例如与这些私钥相关的椭圆曲线。默认情况下,与以太坊或 EVM 兼容的链依赖于 secp256k1 椭圆曲线。
完成以下步骤以创建临时私钥,类似于非托管加密钱包管理其密钥的方式,并将其转换为 PKCS #8 格式,从而使其兼容导入 Amazon KMS:
- 生成一个临时 secp256k1 私钥,打印其公钥(供稍后比较),然后提取原始私钥:
结果将是编码为十六进制字符串的原始私钥,类似于非托管 EOA 钱包存储密钥的方式。
- 按照 Amazon KMS 的要求,使用
openssl
命令重组 ASN.1 结构并以 PKCS #8 格式存储新密钥:
在此示例中,我们转换密钥的十六进制字符串表示形式以及序列化的 ASN.1 参数:
302e0201010420
定义 ASN.1 序列的开始并指定不带公钥的总长度。a00706052b8104000a
定义了编码为 OID 1.2.132.0.10 的named_curve
参数,即 secp256k1。OID 可以被视为加密算法等公认标准的全球注册机构。
有关 ASN.1 和用于重组密钥结构的值的更多详细信息,请参阅 Stackoverflow 1 或 Stackoverflow 2。
正如上一节所指出的,ASN.1 结构也可以使用更高级别的语言(如 Python)进行组装和序列化,如以下代码片段所示。在此示例中,我们使用预定义值来避免额外的外部依赖关系。
-inform DER
和 -outform DER
标志表示我们正在导入和导出 ASN.1 描述的二进制格式的纯文本密钥。
或者,要根据转换后的私钥计算公钥并将其与最初保存的公钥进行比较,请完成以下额外步骤:
- 解析重新创建的私钥并打印出公钥:
- 比较初始和重新创建的公钥,例如使用
diff
并确保它们相等:
使密钥 PKCS #8 兼容
你可以从以下 GitHub 存储库下载 shell 脚本,自动将以 64 个字符的十六进制字符串表示的 secp256k1 私钥转换为编码为 DER 的有效 PKCS #8 结构。在不克隆整个存储库的情况下直接下载脚本需要你先通过 chmod +x script_name
添加运行权限:
如果成功,该 reassemble_pkcs8.sh
脚本会将 DER 编码的私钥写入本地文件夹。
现在,您可以使用这些文件将密钥导入 Amazon KMS。有关如何将重新组装的私钥导入 Amazon KMS 密钥的说明,请参阅导入 Amazon KMS 密钥的密钥材料。高级步骤如下:
- 创建 KMS 密钥。
- 下载加密封装密钥。
- 使用包装密钥对本应导入的密钥材料进行加密。
- 导入新密钥。
有关自动执行密钥导入过程的更多信息,请参阅将以太坊私钥导入到 Amazon KMS。
结论
在这篇文章中,我们简要介绍了不同的钱包类型,并讨论了一些优缺点。我们还解释了为什么密钥管理总体上具有挑战性,以及为什么将与密钥管理相关的任务转移到专门构建的服务中是有益的。此外,我们还解释了如何使用 PKCS #8 和 ASN.1 标准存储私钥和公钥,以及不同的格式如何有利于不同的用例,例如网络传输。本文最后我们演示了如何使非托管钱包使用的原始椭圆曲线私钥与 Amazon KMS 兼容。
你可以使用这篇文章中提供的说明来创建自己的私有区块链密钥并将其转换为 PKCS #8。使用将以太坊私钥导入到 Amazon KMS 中描述的机制将密钥安全地导入 Amazon KMS。最后一步,创建并签署与以太坊兼容的交易,如如何使用 Amazon KMS 签署以太坊 EIP-1559 交易中所述。
作者简介
David-Paul Dornseifer 是亚马逊云科技全球专家组织的区块链架构师。他专注于帮助客户设计、开发和扩展区块链交易管理和密钥托管解决方案。
孙超群是一名解决方案架构师,负责基于亚马逊云科技云计算解决方案的架构咨询、设计和实施,帮助企业与技术一起发展。他还热衷于为客户设计和构建端到端的区块链解决方案。