一道Question,让我搞懂了工作量证明
最近在研究各大harness产品逆向项目,解析它是怎么把官方客户端的请求链路复刻出来。AI 讲得很细,可我满耳朵都是黑话:签名、HMAC、网关、映射表、PoW。我回了一句:“能不能说人话。”
黑话翻译完,我发现整条链路里原理最简单的,恰恰是这个 PoW。今天只讲它,俗称工作量证明
本文的灵感来源项目如下:
客户端每说一句话,都要先做一道傻题
那个项目复刻的协议里,客户端每往服务器发一次请求,都得先算一道题。不算完,不准寄。
题是这样的。有一种函数叫哈希,你把它想成一台搅碎机:不管丢进去什么——一句话、一张图、一整部电影——出来的都是一坨固定长度的指纹。这台机器有个要命的特性:没法反推(哈希的性质)。你拿着指纹,没法倒推出输入是什么,只能不停地试。
PoW 就是拿”没法反推”出的题。服务器说:我给你一个题目,你去找一个数字,把它拼在题目后面一起丢进搅碎机。我要指纹开头 8 位全是 0。找不到,就换下一个数字。
难点就在这儿。搅碎机的输出毫无规律,你没法推算哪个数字能中,只能一个数一个数地硬试。每试一次,就像开一次盲盒。
我不信,我手算了一遍
光讲道理没用,我朝着题自己算了一遍(数字是示意)。题目 abc123,要求指纹的第一个字节全是 0:
- 试 0,搅出来
9f2e8a…,不是 - 试 1,
4b1c07…,不是 - 试 2,
77ad31…,不是 - 一路试到 178,
00b4d9…。第一个字节是00,中了
答案就是 178。交回去,服务器验卷只要一次哈希:它自己算一遍 搅碎("abc123" + 178),看到开头是 0,通过。一毫秒都花不掉。
这件事有多不对称呢。答题的人平均要试 256 次——8 位 0,每多 1 位难度翻倍。验题的人,一次就够。
我原以为它防偷看,我想错了
说个丢人的。我最初是从比特币接触到 PoW 的,一直以为它是密码学的一部分,防的是偷看、是篡改。
全想反了。PoW 一点都不防偷看,请求内容该是明文还是明文。它防的是另一件事:用极低的成本,重复地作恶。
你交出正确答案这件事本身,就证明你刚刚花了 CPU 时间。服务器不需要信任你这个人,答案自带证据。所以它叫”工作量”证明——重点在”干活”,不在”算力”。
那服务器记个 IP 限流,不就行了?
这是我冒出来的第一个念头。记每个 IP 的访问次数,超了就拒,多直接。
想了一圈,PoW 有两个限流给不了的东西。
一个是成本结构。真人发一次请求,多花零点几毫秒算题,无感。脚本想刷量,一秒钟发一万个请求,就得老老实实算一万道题。而且每道题都不一样——那个协议里的题目,是拿我的 Key、会话、时间戳现场拼的,攒不下来答案。刷得越猛,亏得越狠。
另一个更妙:服务器什么都不用记。限流要记”这个 IP 刚才来过几次”,PoW 不用——答案本身就是证据,验一次就完。没有状态,就没有存储,也没有隐私负担。
一个设计,同时解决了成本、状态、防重放。说实话,这是我第一次觉得一个安全设计称得上”优雅”——通常这个词出现的地方,堆的都是麻烦。
顺便,比特币也是它
难度是可以拧的。要 8 个 0,平均试 256 次;要 16 个 0,平均六万多次。比特币把难度调到了全世界矿工要抢 10 分钟才出一个块。同一个原理,难度差了成千上万倍。
所以我一直觉得 PoW 被比特币耽误了——名字听着像跟挖矿赚钱有关,容易被当成炒币的周边技术。其实它防的是重复作恶,跟钱没有半点关系。当然,这是我个人的看法;你要是做高并发系统,反对意见也来得直接:无状态验证换的是一次哈希的开销,量大了,这笔账确实要另算。
傻题旁边,还站着一个印章
最后补一个当时的意外。我以为一道傻题就够了,结果扒到底发现,傻题旁边还挂着一个 Ed25519 签名。
俩货分工很清楚。签名证明”这请求是我发的、没被改过”,管冒充和篡改;PoW 证明”你是活的、付出了成本”,管刷量。光有签名,脚本可以拿着真 Key 狂刷;光有 PoW,内容可能在半路被改。缺一个,防线就漏风。
说点别的
以前我觉得”工作量证明”这种词,属于比特币圈和学术论文,离我这种小白十万八千里。直到我在一个每天要用的工具里撞见它。
好的安全设计,气质是相通的:让守规矩的人无感,让想钻空子的人买单。
看懂了这一道傻题,你再看市面上那些”验证你是人类”的设计,眼光会完全不一样~
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时