加密交易所的安全问题出在速度,而不是密码学
Binance 20分钟被盗63亿美元,暴露的是交易速度问题而非密码学缺陷。真正能阻止快速盗币的,是这些机制。

二十分钟。据报道,攻击者用这么长时间从币安转走了63亿美元,比大多数事件响应团队拉起一个视频会议所需的时间还短。如果只记住一件事,那就是:加密交易所的安全问题不出在数学上。签名大概是有效的,密钥也做了密钥该做的事。问题在于速度,现代交易所能把一个被盗的凭证,在任何人还没来得及说一声“等等”之前,就变成数十亿美元不可逆的结算。
早期报道称,入口是一名员工被攻陷的设备,交易所承诺赔付损失并配合执法部门。这些都不该让你安心。一台笔记本电脑就挡在攻击者和63亿美元之间,这算不上安全架构,只是一个迟早会出事的意外。我们花了十年加固这个技术栈的错误层面,这次劫案就是来讨债的。
二十分钟是设计缺陷,不是倒霉的一天
故事里最吓人的部分(二十分钟!)其实是最不意外的部分。每一起重大交易所盗窃案都是同样的套路:数月甚至数年的悄悄准备,然后在几分钟的执行窗口内完成。2016年的孟加拉央行劫案也是这样。攻击者在央行网络里潜伏了几个月,然后一口气发出大量伪造的SWIFT报文。他们想拿走十亿美元,最后只拿到8100万,还是因为一家代理银行的一名细心员工发现了异常,才拦住了剩下的部分。这里面靠的是运气。运气不是一种控制手段。
加密交易所之所以特别,也格外脆弱,是因为它同时具备三种特性,而这三种在传统金融中几乎不会同时出现:结算是终局性的,没有撤回按钮;结算是快速的,没有审核窗口;结算是不记名的,谁掌握签名能力,谁就掌握资金。电汇可以因为一通打给代理银行的电话而被冻结;一批已经签好的区块链交易却无法撤销签名。一旦攻击者摸进交易所的签名链路,他们偷的就不是钱,而是把钱“传送”走了。
所以,二十分钟这个数字本身并不是丑闻。丑闻在于,这套系统的设计让二十分钟就已经足够。如果你的架构允许几十亿美元在一顿午饭的时间里离开大楼,攻击者就不需要多快,是你自己把速度给他们准备好了。
更好的密码学也救不了这家交易所
每当出现九位数或十位数的盗窃新闻,人们的第一反应总是:密钥管理一定有问题,应该用HSM、多方计算,或者更大的多签门槛。行业已经把这个教训学得很透,大多数主流交易所现在确实在用HSM和MPC。但盗窃案依然不断,因为这个前提本身就错了。密码学只回答一个问题:这个请求是真的吗?它回答不了劫案期间最关键的那个问题:这个真实的请求,该不该发生?
如果入口是员工被攻陷的笔记本电脑,一个拥有有效凭证、有效MFA令牌、能访问提币编排层的会话,那么系统产生的每一个签名在密码学上都无可挑剔。HSM不知道操作它的人正在被远程控制。当攻击者攻陷足够多参与方的终端时,MPC也帮不上忙,这正是6.25亿美元Ronin桥盗窃案的手法:九个验证者密钥里拿下五个,靠的是攻陷机器,而不是破解数学。就连比特币本身被“黑”的传闻,一经审视也往往站不住脚。我们在研究一个被大肆炒作的PHP比特币漏洞时就发现,密码学从来不是弱点。真正的弱点,永远是一个可信系统被一个不该操作它的人,按照设计的方式使用的那一刻。
密码学保护的是密钥。而在密钥被按照设计正常使用的那一刻,数学本身什么也保护不了。
监控赢不了二十分钟的时钟
第二个惯性反应是检测:更好的监控、异常检测,再加上一个盯着转账的AI。交易所确实有这些,而且它们确实触发了,我们正是靠它们才知道这次劫案用了二十分钟。但检测和预防是两种不同的产品,它们的延迟预算完全不同。在成熟的安全运营中心,从一条高置信度告警到一个有权限暂停提币的人,即便状况很好也要花几十分钟:呼叫值班人员,确认不是误报,逐级上报给能拉下那根大闸的人,拿到批准,再动手。攻击者的整个行动,都能在这个循环里从容完成。
这是没人愿意计入成本的不对称性。防守方按工作时间配置人手,而攻击者专挑周末和节假日下手,因为那时响应速度会打折扣。而且即便告警瞬间触发,告警也不是急停开关,真正的开关是人。这套戏码在加密领域之外我们也见过:孟加拉央行的盗窃是被一个人而不是一个系统拦下的,而那个人差点就不在岗。如果你的最后一道防线是“希望有人正盯着仪表盘”,那你其实没有最后一道防线。这个道理远不止适用于交易所,我们在为什么对自主智能体而言遏制胜过监控一文中也提出过类似观点:只能观察、无法干预的监控,不过是对你失败过程的一段录像。

赔付损失是一种表态,不是修复
币安表示将赔付全部损失,而且公平地说,这家公司之前做过:2019年被盗7000个BTC后,它的SAFU保险基金让用户完全得到了补偿。当时市场几乎没有波动,现在大概也不会。但我们得诚实地看清“我们会赔”在架构层面意味着什么:什么都不意味着。保险是用来吸收失败的资产负债表工具,而不是预防失败的工程手段。它把一场灾难变成了一笔费用,对交易所来说这很理性,对下一个攻击者却毫无影响,因为他面对的依然是同样的二十分钟窗口。
还有一个规模问题,行业里没人愿意公开说。63亿美元的损失,远远超过整个加密行业可用的全部保险容量。地球上只有少数交易所有能力自我承保这种损失。而其他所有规模较小的平台(至少有数百家持有大量用户资金)实际上都在赌:出事的不会是自己。这正是存款保险和审慎监管在银行业要填补的缺口,所以“币安是否应该因疏忽的安全措施而被起诉?”这种直觉,哪怕粗糙,指向的也是真实存在的问题。一个世纪前我们就已经决定:持有他人资金的机构,无权自行选择风险偏好。加密行业则花了十五年时间,一起劫案一起劫案地重新争论这个问题。
熔断机制:市场早已发明的解法
令人沮丧的是,金融界几十年前就解决了这个问题,只是方向不同。1987年股灾之后,股票交易所引入了熔断机制,在价格剧烈且快速波动时暂停交易。没人认为停盘能消除欺诈或崩盘;它的意义在于把一个失控的过程变成一个有人监督的过程,为人的判断争取时间。同样的逻辑适用于资金流出,而且简单到几乎令人尴尬:无论签名多么有效,任何平台都不应该在短时间内流出超过其资产一小部分的资金。
提币熔断器是一个坐落在签名链路中的策略引擎,它把速度本身视为异常。关键在于,它不去判断请求是否真实,而是假定每一个请求都可能既真实又恶意,然后依然限制爆炸半径:
from dataclasses import dataclass
from datetime import datetime, timedelta
@dataclass
class WithdrawalPolicy:
window: timedelta = timedelta(minutes=30)
max_outflow_pct: float = 2.0 # of hot-wallet balance per window
hard_freeze_pct: float = 5.0 # trip the breaker entirely
large_threshold_usd: float = 1_000_000
large_delay: timedelta = timedelta(hours=24)
class CircuitBreaker:
def __init__(self, policy: WithdrawalPolicy):
self.policy = policy
self.recent: list[tuple[datetime, float]] = []
self.tripped = False
def authorize(self, amount_usd: float, hot_balance_usd: float) -> str:
if self.tripped:
return "REJECT: breaker tripped, manual review required"
now = datetime.utcnow()
cutoff = now - self.policy.window
self.recent = [(t, a) for t, a in self.recent if t > cutoff]
outflow_pct = 100 * (sum(a for _, a in self.recent) + amount_usd) / hot_balance_usd
if outflow_pct > self.policy.hard_freeze_pct:
self.tripped = True
return "HALT: outflow exceeded safety threshold, withdrawals frozen"
if outflow_pct > self.policy.max_outflow_pct:
return "QUEUE: velocity limit reached, withdrawal delayed"
if amount_usd > self.policy.large_threshold_usd:
return f"DELAY: held {self.policy.large_delay} for review"
self.recent.append((now, amount_usd))
return "APPROVE"
用这次劫案的数字来看它能带来什么。如果热钱包里哪怕只有63亿美元的10%,那么一个按热余额5%设置的硬性冻结,就能把自动化损失上限控制在约3100万美元,那是糟糕的一个下午,而不是生死存亡的事件。更重要的是,攻击者二十分钟的冲刺会变成持续数天的慢爬,这样监控团队终于有机会出场。整件事的重点不是在智力上压过攻击者,而是拉长时间,直到有人赶来。这就是经典意义上的防御性工程:把系统设计成最坏的失败也乏味无奇。

提币延迟与“无聊银行业”的价值
熔断机制处理的是速度,延迟机制处理的是规模。传统金融体系的秘密武器并不是什么精巧的技术,而是摩擦。电汇可以撤回,ACH要等上几天,大额转账会触发冻结期,并通过另一条渠道回拨到已知联系人进行确认。加密行业为了把即时终局结算当作卖点,把这些摩擦全部去掉了。但你完全可以在提币环节有选择地重新引入摩擦,而不必动用用户真正在乎的交易体验:
- 大额提币加时锁定。超过阈值的提币在可见的队列中等待24小时。用户可以提前规划,攻击者却做不到,每多延迟一小时,入侵就多一小时被发现的机会。
- 热钱包硬性上限。只在线保留满足24小时正常提币所需的资金,对大多数平台而言,这通常只占资产的个位数百分比。冷钱包的转移需要多方参与、耗时数天的仪式,任何凭证都无法加速。
- 新增地址白名单,变更延迟生效。新的提币地址需要延迟激活,并经过带外确认。这样就能堵住入侵期间常见的手法:偷偷替换收款地址。
- 签名权限分段。无论经过多么严格的认证,任何单个终端、角色或会话都不能转出超过上限的金额。当爆炸半径足够小,入口的重要性就随之下降。LiteLLM供应链事件给Python生态上了一课:开发者的机器是最脆弱的目标。
- 公开附带负债的储备证明。这不是防盗控制手段,但它是一根偿付能力的预警线,能让粉饰真相的选项提前出局。
注意这些措施都不需要什么:不需要新的密码学,不需要新的硬件,也不需要新的科学。它们只是政策。它们同样不受欢迎,因为每一条都是产品经理的噩梦(摩擦、延迟、限额),而且交易所的经济模型奖励的是吞吐量和一切即时化。这种张力是真实存在的,而行业迄今的答案,是为了顺滑的用户体验而接受灾难性的尾部风险。一场63亿美元、耗时二十分钟的劫案,就是这笔交易到期时的样子。
速度是一种选择,所以要有意识地选择
事件响应里有句老话:当秒数很重要时,我们以天甚至周为单位打补丁。这次劫案把它颠倒了过来,当秒数很重要时,钱在几分钟内就转走了,而防守方的整个流程却是为一个更慢的世界设计的。靠更聪明的告警或更强的密钥无法解决这个问题,因为攻击者既没有破解密钥,也没有躲避告警。他们只是按照你的系统设计的方式使用它,以你设计的运行速度。
所以,对每一位交易所工程师(坦白说,也对每一位构建价值流转系统的工程师)来说,最诚实的问题不是“我们如何永远把攻击者挡在外面?”你做不到。笔记本会被攻陷,人会被钓鱼,供应链会被投毒。真正的问题是:当有人闯进来时,你的架构是快速失败还是缓慢失败?眼下行业给出的答案是:快速、终局、而且全程直播。速度上限、延迟提币和热钱包硬性限额,正是改变这个答案的办法。技术本身并不难,难的是愿意接受一点摩擦的意志。如果行业自己不肯选择这份摩擦,那么监管者,眼看着63亿美元的损失在一杯咖啡的工夫里发生,迟早会替它们做这个选择。


