Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
基础设施与运维阅读约 11 分钟

热钱包与冷钱包:密钥托管模型、威胁边界与验证工作流

一份关于热钱包与冷钱包的实用指南,将密钥存储架构与设备标签区分开来,并提供可运行的检查方法,以验证您实际运行的是哪种模型。

TL;DR

热钱包和冷钱包描述的是签名密钥存放的位置以及它们是否可被联网进程访问,而不是您购买了哪个品牌的设备。热钱包将密钥保存在联网机器可直接使用的软件中;冷钱包将密钥保存在签名时离线的环境中,仅通过边界传递已签名的负载。本文为您提供边界的心智模型、可运行的检查以确认您实际运行的模型、用于衡量暴露程度的结果表流程,以及针对最常见错误配置的故障排除。本文有意不提及具体钱包产品,因为托管模型比包装盒上的标签更重要。

直接答案与范围

热钱包是指私钥保存在联网机器上的软件中、签名时在线进程可以访问密钥材料的任何钱包。冷钱包是指私钥保存在签名时离线的环境中、只有交易或已签名负载跨越边界的任何钱包。区别在于密钥边界,而不在于产品被称为应用、浏览器扩展、硬件设备还是一张纸。

本文涵盖托管模型、每种模型产生的威胁边界,以及可复现的方法来验证您实际运行的是哪种模型。它不推荐特定的钱包供应商,也不声称 OnFinality 或任何其他提供商有任何经过测量的安全成果。在数字有用之处,本文提供的是在您自己的设置上进行测量的流程,而不是编造一个值。

  • 热钱包:签名时密钥可被联网进程访问。
  • 冷钱包:签名时密钥离线保存;只有负载跨越边界。
  • 温钱包或混合设置:密钥在线,但签名受策略、审批或第二因素控制。
  • 产品上的标签不决定模型;运行时边界才决定。

假设与前提条件

以下流程假设您拥有一个自托管钱包,您控制密钥材料,终端中可用 curl 和 Python 3,并且可以访问您所用网络的 JSON-RPC 端点。将 RPC_URL 替换为您自己的端点;不要将真实私钥粘贴到本文的任何命令中。如果您需要一个用于只读检查的托管端点,请参阅多链 RPC 端点指南和RPC 端点指南了解端点的结构。

您还应该知道您的钱包面向哪个网络和链 ID,因为指向错误链的钱包可能看起来正常工作,但实际上却在为另一个网络签名交易。如果您不确定哪个链 ID 适用,网络目录列出了支持的网络。

密钥边界的心智模型

将钱包视为三个可分离的部分:密钥存储、签名和广播。在热钱包中,这三者都可以在同一个在线进程中运行。在冷钱包中,密钥存储和签名发生在离线环境中,只有已签名的交易被带到在线机器进行广播。这种分离改变了威胁模型:攻破您在线机器的攻击者通常可以访问热密钥,但如果不同时攻破离线环境或传输步骤,就不应该能够访问冷密钥。

边界的强度取决于其最薄弱的跨越点。如果您拍摄了助记词、将其输入在线密码管理器,或在密钥解锁时曾在连接过互联网的设备上签名,那么您实际上已将密钥移入了热区。一个有用的测试是问:在交易签名的瞬间,联网进程能否在没有人工物理移动数据跨越气隙的情况下读取或使用密钥? 如果答案是肯定的,无论其营销如何,都应将钱包视为热钱包。

  • 密钥存储:秘密材料在静止状态下存放的位置。
  • 签名:将交易转换为已签名负载的过程。
  • 广播:将负载提交到节点或 RPC 端点的在线步骤。
  • 冷模型要求签名在广播机器无法访问密钥的情况下进行。

验证您实际运行的模型

在信任标签之前,确认运行时事实。以下检查是只读的,并使用占位符端点。它们验证链身份和账户状态,这是任何托管决策的基础;它们本身不能证明密钥隔离,但能捕捉到钱包指向错误网络或意外账户的常见故障。

curl -s -X POST "$RPC_URL" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'

curl -s -X POST "$RPC_URL" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"eth_getBalance","params":["0xYOUR_ADDRESS","latest"]}'

可复现的暴露检查流程

使用以下流程为您操作的每个钱包记录签名时密钥边界是热还是冷。每个钱包运行一次,并将结果存储在表格中。不要编造值;记录您观察到的内容。

下表是一个模板。根据您自己的观察填写每一行,并将表格与操作笔记一起保存,以便在任何配置更改后重新运行检查。

  • 步骤 1:确定签名环境(手机、笔记本电脑、浏览器扩展、硬件设备、气隙机器)。
  • 步骤 2:在签名时,记录该环境是否有活跃的网络连接。
  • 步骤 3:记录已签名负载如何到达广播步骤(同一进程、二维码、USB 文件、手动复制)。
  • 步骤 4:记录密钥材料是否曾被输入、拍摄或同步到在线系统中。
  • 步骤 5:根据步骤 2–4 将钱包分类为热、冷或混合,而不是根据产品名称。

可运行的诊断:在广播前检查签名请求

降低热钱包风险的一种实用方法是在广播之前检查交易。下面的 Python 代码片段构建一个最小的 JSON-RPC 调用,以估算 gas 并获取地址的 nonce,从而让您确认交易目标链是您期望的。它仅使用占位符,不签名任何内容。

针对您自己的端点运行它,并将返回的链 ID 与钱包显示的网络进行比较。不匹配是一个强烈信号,表明钱包配置错误,在纠正之前应视为不安全。

import json, urllib.request

RPC_URL = "RPC_URL"
ADDRESS = "0xYOUR_ADDRESS"

def rpc(method, params):
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": method, "params": params}).encode()
    req = urllib.request.Request(RPC_URL, data=body, headers={"Content-Type": "application/json"})
    with urllib.request.urlopen(req, timeout=10) as resp:
        return json.loads(resp.read())

print("chainId:", rpc("eth_chainId", []))
print("nonce:", rpc("eth_getTransactionCount", [ADDRESS, "pending"]))
print("gasPrice:", rpc("eth_gasPrice", []))

预期的验证结果

当上述检查成功时,您应该看到一个与您打算使用的网络匹配的链 ID、一个仅在您发送交易时才会增加的 nonce,以及一个对当前网络状况合理的 gas 价格。如果链 ID 与钱包显示的不同,请停止并在签名任何内容之前修复配置。如果 nonce 意外偏高,可能有另一个签名者在使用同一地址,这是一个托管危险信号。

对于冷设置,验证结果还包括一个人工可观察的事实:签名环境在签名时刻没有网络连接,并且负载通过您可以描述的通道跨越边界。如果您无法描述该通道,请将钱包视为热钱包。

常见错误配置的故障排除

大多数托管故障是配置故障,而不是密码学破解。以下列表涵盖了最常将名义上的冷钱包变为热钱包,或导致热钱包在错误链上签名的模式。

如果硬件设备在密钥解锁时连接到在线计算机,则该会话期间边界被削弱。如果助记词被输入在线恢复工具,则应认为密钥已暴露并需要轮换。如果钱包在一个网络上显示余额但在另一个网络上交易失败,请使用上述诊断验证链 ID,然后再假设是节点问题。

  • 助记词输入在线密码管理器或云笔记:视为热钱包并轮换。
  • 硬件设备在浏览期间保持解锁和连接:边界被削弱。
  • 钱包指向错误的链 ID:交易可能为意外网络签名。
  • 多个签名者共享地址:nonce 冲突和托管不清晰。
  • 备份未加密存储在联网驱动器上:密钥材料可在线访问。

局限性与权衡

冷托管减少了在线攻击面,但增加了操作摩擦:每笔交易都需要物理步骤,如果备份不足,设备丢失或损坏可能意味着永久损失。热托管方便且适用于小额运营余额,但它将风险集中在在线机器上。混合模型试图通过将密钥在线保存在审批策略之后来平衡两者,这减少了随意暴露,但并未消除在线边界。

没有哪种托管模型能消除验证您正在签名内容的需要。一个签署恶意负载的冷钱包仍然是损失。将边界与交易检查、地址允许列表以及针对可信端点的定期对账相结合。对于运行专用基础设施的团队,专用节点服务和API 服务页面描述了托管访问如何融入操作设置,而RPC 定价页面解释了端点使用如何计量。

后续步骤

首先使用暴露检查流程对您操作的每个钱包进行分类,然后修复任何标为冷钱包但未通过边界测试的钱包。轮换曾在线暴露的密钥,并为每个冷设置记录负载传输通道,以便边界可审计。如果您需要可靠的端点来进行本文中的只读检查,请查看多链 RPC 端点指南和RPC 端点指南,然后从网络目录中选择与您网络匹配的端点。有关具体的端点和提供商建议,请咨询 RPC Assistant,而不是将本文视为提供商列表。

永远不用担心基础设施

OnFinality 消除了 DevOps 的繁重工作,让您能够更聪明、更快地构建。

开始