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

热钱包与冷钱包:密钥托管如何改变你的威胁模型

一份实用指南,说明热钱包与冷钱包在密钥管理层面的差异,并提供可运行的诊断方法,用于验证你的签名密钥实际存放在哪里。

TL;DR

热钱包与冷钱包的真正区别不在于你安装的应用或购买的设备,而在于交易签名时私钥所在的位置,以及因此哪些攻击者能够接触到它。热钱包将密钥保存在联网机器的软件中,签名速度快,但密钥与浏览器、依赖项和远程代码共享同一攻击面。冷钱包将密钥离线保存,在生成签名前需要明确的物理或气隙步骤,以牺牲便利性换取更小的远程攻击面。本文构建签名边界的心智模型,提供可运行的诊断方法以验证密钥的实际存放位置,并解释如何结合两种模型,同时避免误以为 2FA 能把热钱包变成冷钱包。

直接答案:签名边界,而非设备类别

加密货币热钱包与冷钱包的区别在于创建签名时私钥所在的位置。在热钱包中,密钥被加载到联网设备上运行的软件中,因此任何能够读取该内存、密钥库文件或环境变量的进程都可能签署交易。在冷钱包中,密钥保存在正常操作期间无法通过网络访问的设备或介质上,每次签名都需要将未签名交易刻意传输到签名环境,再将签名结果传回。

这一区别比营销标签更重要。浏览器扩展、移动应用、服务器端签名服务和硬件设备都可以被称为“钱包”,但它们将密钥置于截然不同的威胁模型中。有用的问题不是“这是热钱包还是冷钱包?”,而是“什么能够接触到密钥,以及在签名存在之前必须发生什么?”

  • 热钱包:签名时密钥材料存在于在线软件中。
  • 冷钱包:密钥材料保持离线;只有交易跨越边界。
  • 温钱包或混合模式:密钥在线,但签名需要审批步骤,这减少了自动化,但并未消除远程攻击面。

本指南的假设与范围

本文假设你已经理解钱包存储的是密钥而非代币,并且地址由公钥派生。内容聚焦于开发者和基础设施团队的自托管与运营托管,而非交易所账户余额。诊断使用标准工具:shell、Node.js、Python 以及针对你控制的 RPC 端点的 curl。

在这些检查中,如果你需要具体的 RPC 端点来读取链上状态,请参阅 RPC 端点指南 了解背景,并使用 RPC 助手 获取具体的提供商推荐。本页专注于托管方法论,因此无论你使用哪条链或哪个提供商,这些检查都保持有效。

心智模型:密钥从不移动,交易移动

将私钥想象成一枚只存在于一个房间里的印章。热钱包将印章放在一个有开放网络端口的房间里。冷钱包将印章放在一个没有网线的房间里,你通过一个槽口传递纸张。区块链只能看到盖章后的结果,因此安全属性完全来自于控制谁能进入这个房间。

这个模型解释了几种常见的混淆。热钱包上的双因素认证保护的是登录或审批路径,但如果恶意软件能够直接读取密钥文件,它就可以在完全不触发 2FA 提示的情况下签名。反过来,永久插在联网电脑上的硬件设备在密钥存储意义上仍然是冷钱包,但其审批按钮成为关键控制点。边界就是签名步骤,每个运营决策都应据此评估。

  • 密钥位置:在线内存、加密密钥库、操作系统钥匙串、安全元件或纸张。
  • 签名触发:自动、密码门控、2FA 门控或物理按钮门控。
  • 影响范围:一个密钥、一个账户,或由同一助记词派生的整个 HD 钱包树。

诊断 1:在运行中的主机上定位密钥材料

在信任任何标签之前,先验证密钥在签名机器上的实际位置。以下 shell 过程列出常见的密钥文件和環境变量。在暂存主机上运行它,切勿将真实密钥粘贴到共享终端,并将任何命中视为需要调查的发现。

预期验证:在正确配置的冷钱包设置中,签名主机不应显示长期存在的私钥文件,也不应有包含密钥的环境变量。在热钱包设置中,你应该找到恰好是你预期的密钥库或密钥存储,并具有严格的权限。

# List likely key-bearing files (adjust paths to your stack)
find / -maxdepth 6 \( -name '*.pem' -o -name 'keystore*' -o -name 'id_rsa' -o -name '*.key' \) \
  -type f 2>/dev/null | head -50

# Show environment variables whose names suggest secrets
env | grep -Ei 'private|secret|mnemonic|seed|key' | sed 's/=.*/=<redacted>/'

# Check permissions on a known keystore
stat -c '%a %U:%G %n' /path/to/keystore.json 2>/dev/null

诊断 2:通过试运行交易证明签名边界

签名边界只有在你能够证明它时才真实存在。下面的 Node.js 代码片段在本地构建并签名交易,然后打印恢复的地址,以便你确认是哪个密钥生成了签名。在隔离环境中使用一次性密钥运行它。如果同一脚本可以在面向互联网的服务器上无人值守运行,那么无论供应商如何称呼该产品,该服务器都是热签名环境。

预期验证:恢复的地址与你对该密钥预期的地址匹配。如果不匹配,则你的密钥来源或派生路径有误,任何基于此的托管假设都是无效的。

// npm i ethers
import { Wallet, Transaction } from 'ethers';

const PRIVATE_KEY = process.env.PRIVATE_KEY; // throwaway key only
const wallet = new Wallet(PRIVATE_KEY);

const tx = Transaction.from({
  to: '0x0000000000000000000000000000000000000000',
  value: 0n,
  chainId: 1,
  nonce: 0,
  gasLimit: 21000n,
  maxFeePerGas: 1000000000n,
  maxPriorityFeePerGas: 1000000000n,
  type: 2
});

const signed = await wallet.signTransaction(tx);
const recovered = Transaction.from(signed).from;
console.log('signer address:', recovered);
console.log('expected     :', wallet.address);

诊断 3:确认网络能看到什么

链本身从不揭示签名来自热钱包还是冷钱包。它揭示的是地址、nonce 和交易。你可以使用 RPC 调用确认广播的交易源自你预期的地址,这是唯一可用的链上证据。

预期验证:返回交易中的 from 字段与你的签名者地址匹配。不匹配意味着交易由与你假设不同的密钥签名,这正是这些检查旨在捕获的托管故障类型。

curl -s -X POST "$RPC_URL" \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "eth_getTransactionByHash",
    "params": ["0xYOUR_TX_HASH"]
  }' | python3 -m json.tool

结果表:记录托管发现

将每项检查记录在表格中,以便在不同主机和时间之间比较发现。不要编造数值;根据你自己的运行结果填写表格。一个完成的示例结构如下,其中占位行由观察到的输出替换。

检查项主机/环境观察结果预期结果状态
存在密钥文件staging-signer-01(从 find 填写)冷主机上无(通过/失败)
存在密钥环境变量staging-signer-01(从 env 填写)冷主机上无(通过/失败)
密钥库权限staging-signer-01(从 stat 填写)600,仅所有者(通过/失败)
签名者恢复isolated-runner(从 Node 输出填写)匹配预期地址(通过/失败)
链上 fromRPC 查询(从 curl 填写)匹配签名者地址(通过/失败)

表格的价值不在于单个行,而在于行之间的模式。一个通过文件和权限检查但签名者恢复失败的主机存在配置问题,而非托管问题。一个通过恢复但暴露密钥文件的主机存在托管问题,再正确的签名也无法修复。

常见托管故障排查

大多数热钱包与冷钱包相关的事件都属于少数几种模式。按顺序处理它们,因为后面的症状往往掩盖了较早的原因。

  • 签名者恢复不匹配:在假设密钥泄露之前,检查派生路径和链 ID;错误的路径会从错误的地址产生有效签名。
  • 密钥文件可被其他用户读取:先修复权限,然后轮换密钥,因为暴露可能已经发生。
  • 启用了 2FA 但签名仍然自动:审批门控在 UI 上,而非签名路径上;将密钥移到自动化无法触及的边界之后。
  • 硬件设备始终连接:密钥离线,但审批按钮现在是唯一的控制点;验证按钮需要物理在场且无法被脚本化。
  • 以数字方式存储助记词“用于备份”:这会将冷钱包降级为热钱包,因为备份现在可被与热密钥相同的恶意软件访问。

每种模型的局限与权衡

冷存储并非没有代价。每笔交易都需要手动步骤,这使其不适合高频操作、自动做市或服务器端结算。它还引入了新的故障模式:设备丢失、备份损坏以及审批疲劳,导致操作员绕过提供安全性的控制。从未测试过的冷钱包是负债,而非资产。

热钱包并非自动不安全。一个具有狭窄范围密钥、低余额、严格进程隔离和监控的热钱包可以是合适的运营工具。错误在于将热钱包用于长期持有,或用于一旦泄露会转移超过你准备损失价值的密钥。正确的问题不是哪种模型更好,而是哪种价值应放在哪个边界之后。

对于运行自己基础设施的团队,同样的逻辑适用于节点运营。专用节点 让你控制签名服务所通信的 RPC 表面,从而减少对共享端点中断和意外行为的暴露。在确定拓扑之前,请查看 RPC 定价 和 支持的网络。

结合热钱包与冷钱包托管,避免自欺欺人

实用的模式是分层托管:小额热钱包余额用于日常操作,冷储备用于长期持有,并有文档化的策略在两者之间转移价值。策略应指定谁可以批准转账、需要什么证据,以及每次使用前如何验证冷设备。没有该策略,分层只是标签。

一个有用的测试是问:在签名主机上拥有远程代码执行能力的攻击者能做什么。如果答案是“转移热钱包余额”,你的边界正在起作用。如果答案是“派生助记词并耗尽一切”,那么你有一个披着冷钱包名字的热钱包。在签名基础设施每次变更后运行上述诊断,并将任何新的密钥文件或环境变量视为需要审查的边界变更。

  • 保持热钱包余额与运营需求相匹配,而非与便利性相匹配。
  • 在依赖冷设备进行大额转账之前,用小额测试交易验证它们。
  • 记录审批路径并测试它,包括设备不可用的故障情况。
  • 监控签名主机是否有新的密钥材料和意外的出站签名请求。

开发者和运营者的后续步骤

首先在暂存主机上运行三项诊断,并用你自己的观察填写结果表。然后,将系统中的每个密钥映射到一个边界和最大可接受损失。如果密钥超过该阈值,将其移到冷钱包或审批门控边界之后;如果没有超过,记录为什么热钱包模型是可接受的。

对于签名服务所依赖的 RPC 层,使用 API 服务概览 了解托管端点提供什么,并咨询 RPC 助手以获取具体的提供商选择,而非猜测。如果你正在构建更广泛的钱包或签名基础设施,多链 RPC 端点指南 涵盖了端点拓扑如何与跨网络的密钥托管相互作用。

永远不用担心基础设施

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

开始