口令 → 私钥(脑钱包)
对一句话做一次 SHA-256,就得到一整套钱包:WIF、公钥、hash160 和地址。本页把这条路径有多薄完整摊开 —— 也解释为什么任何有资金的脑钱包都会在几秒内被扫走。
请在上方输入内容后点击「转换」。不知道填什么?点「填入示例」即可载入占位符里的演示数据。
本页计算了什么
它取一个口令,用一次 SHA-256 就从中推导出一整套比特币钱包。这就是全部算法 —— 没有盐、没有迭代次数、 也没有内存硬度参数:
本页故意做得「完整」:它把输入字节、摘要以及全部派生值都摊开给你看,好让你亲眼看到:一句你能记住的话,和一个真正 的私钥之间,隔着的究竟有多薄。在后果这件事上,本页同样刻意不留余地 —— 见下。
这里推导出的地址,其背后的短语要么有名到出现在每个攻击者的词表里,要么弱到一次定向搜索就能找到。自动化机器人持续 监控区块链和内存池,脑钱包的入账会在几秒内被扫走 —— 它们通常付出比你更高的手续费,好让自己的花费先被确认。 转进脑钱包地址的资金(包括本页为示例短语显示的那个地址)一定会被拿走。没有办法把本页变得安全; 请改用硬件钱包生成的 BIP39 助记词。
1. 脑钱包的想法,以及它为什么如此诱人
比特币私钥不过是一个 256 位数字,而任何「由一句好记的字符串确定性地算出数字」的函数都能产出它。于是有了一个 难以抗拒的卖点:不用纸备份、不用金属板、没有会弄丢的助记词 —— 钱包就活在你脑子里,可以在世界任何地方、任何一台电脑上、 永远地重新生成。2011–2013 年间,整篇整篇的博客都在推荐这种做法。
问题不在哈希函数上,问题出在「好记」这两个字上。私钥必须对攻击者不可预测;而一句你不需要笔记就能想起来的短语, 按定义就来自语言空间中那块狭小且被大量记录的区域 —— 人类觉得好记的地方。你并没有创造出 256 位秘密,你只是创造了一个 查询条目。
下面两种失效模式,几乎覆盖了所有真实的脑钱包失窃:
- 预计算。 攻击者一次性哈希几百万条候选短语、推导出地址并保存下来。此后,向其中任何地址的任何一笔入账 都会被瞬间发现 —— 短语是否「保密」已经无关紧要,因为攻击者根本不需要再猜一次。
- 定向搜索。 如果你的短语带有个人色彩,那么一个对你略知一二的攻击者(「喜欢托尔金,爱马」)需要 搜索的空间远小于 2²⁵⁶。而由于每次猜测只要一次 SHA-256,这个空间便宜到可以随便枚举。
2. 为什么单次、无盐的 SHA-256 是灾难性的密钥派生函数
SHA-256 是一个快速、通用的哈希。它的设计者恰恰优化了让密钥派生函数失败的那项性质:每美元每秒的最大吞吐量。 当你把一句短语哈希一次、直接拿结果当私钥时,攻击者测试一次猜测的成本就是一次 SHA-256 求值 —— 以纳秒计, 在专用芯片上甚至以皮秒计。
| 口令 KDF 应具备的性质 | 脑钱包(单次 SHA-256) | 为什么重要 |
|---|---|---|
| 随机的盐,与记录一起保存 | 没有 —— 短语本身决定密钥 | 没有盐,一次预计算就能永久服务所有目标、所有地址。盐还能挡掉彩虹表,并让相同短语产生不同密钥。 |
| 可调的工作因子(迭代次数) | 1 次,无法调整 | 硬件变快时,每次猜测的成本无法随之提高。2011 年昂贵的东西,今天已经免费。 |
| 内存硬度 | 没有 —— 只有几百字节状态 | ASIC 与 GPU 最爱低内存算法。内存硬函数迫使攻击者去买内存与内存带宽,而这两样不像哈希算力那样容易堆。 |
| 对弱输入不产生「凭空增强」的错觉 | 没有 —— 输入空间就是攻击者的词表 | 密钥的安全性等于短语的熵,而不是哈希的强度。哈希无法创造从未存在过的熵。 |
最后一行就是全部真相。哈希函数不创造不可预测性,它只是忠实保留输入的不可预测性 —— 同样也忠实地保留输入的 可预测性。
字典攻击的算术
假设攻击者手里有 1,000 万条候选短语(下载来的口令字典、名言、歌词、维基百科句子,再加上网上所有谈过脑钱包的短语)。 穷举它所需的时间就是「语料规模 ÷ 吞吐率」,而原始 SHA-256 的吞吐率高得惊人:
| 攻击者吞吐率 | 穷举 10⁷ 条语料所需时间 | 大致对应什么设备 |
|---|---|---|
| 10⁴ 次/秒 | 1,000 秒 ≈ 17 分钟 | 一个 CPU 核心跑着朴素脚本 |
| 10⁵ 次/秒 | 100 秒 | 优化过的单 CPU 核心 |
| 10⁶ 次/秒 | 10 秒 | 笔记本 GPU + 调优过的工具 |
| 10⁹ 次/秒 | 0.01 秒 | 一块现代显卡,跑原始 SHA-256 |
| 10¹¹ 次/秒 | 0.0001 秒 = 100 微秒 | 小型集群或 FPGA 农场 |
请再读一遍第一行:一千万条语料,在一个 CPU 核心上几分钟就跑完了。最后一行则解释了为什么扫币机器人被形容为 「瞬间」。再看同样的语料换成真正的密钥派生函数要多少钱 —— 唯一变化的就是「一次猜测的单价」:
| 对每条候选短语施加的 KDF | 每次猜测的哈希运算量 | 按 10⁹ 哈希运算/秒折算 | 跑完 10⁷ 条语料 |
|---|---|---|---|
| 单次 SHA-256(本页) | 1 | 1,000,000,000 次/秒 | 0.01 秒 |
| 双重 SHA-256 | 2 | 500,000,000 次/秒 | 0.02 秒 |
| PBKDF2-HMAC-SHA512,2048 轮(BIP39) | 约 4,096 | 约 244,000 次/秒 | 约 41 秒 |
| PBKDF2-HMAC-SHA512,2,097,152 轮 | 约 4,194,304 | 约 238 次/秒 | 约 11.7 小时 |
| scrypt N=2¹⁵, r=8, p=1(每次约 32 MiB) | 受内存限制 | 单机每秒数百到数千次 | 数小时到数天,且受内存限制 |
| Argon2id,64 MiB,t=3 | 受内存限制 | 单机每秒数百到数千次 | 数小时到数天,且受内存限制 |
最后两行有意只做定性描述:它们的成本取决于攻击者能负担多少内存,而不是能算多少哈希,所以给一个数字反而会误导。 这恰恰就是内存硬 KDF 的意义。
3. 人类自己选的口令,无论看起来多长,熵都只有几十位
熵不是字符串的属性,而是选择它的那个过程的属性。如果你真是靠掷骰子在 95 个可打印字符里随机生成那句
示例短语,它的 28 个字符会携带 28 × log₂(95) ≈ 184 位熵,那它确实无法被攻破。但你并没有这么做:你(或者
那篇博客的作者)选的是一句「别人也觉得好记」的话,而这类句子的集合很小,而且被大量编目。字符串很长,
但选择很短。
| 口令类型 | 表面长度 | 示意性的攻击搜索空间 | 按 10⁹ 次/秒所需时间 |
|---|---|---|---|
| 单个字典词 | 约 8 个字符 | 约 10⁵ | 100 微秒 |
| 两个字典词 + 数字 | 约 12 个字符 | 约 10¹⁰ | 10 秒 |
| 四个常见词(XKCD 风格) | 约 28 个字符 | 约 2⁴⁴ ≈ 1.76 × 10¹³ | 17,592 秒 ≈ 4.9 小时 |
| 某本名书或名曲里的一句 | 40 个字符以上 | 所有已数字化书籍、歌词、名言的全部句子 —— 2³⁵ 量级 | 约 34 秒 |
| 12 词 BIP39 助记词(如实计量) | 约 93 个字符 | 2¹²⁸ | 约 10²² 年 |
| 随机 256 位密钥 | 64 个十六进制字符 | 2²⁵⁶ | 约 10⁶¹ 年 |
「搜索空间」这一列是量级层面的示意,不是实测 —— 但把它换算成时间的算术是精确的,而这就是全部论证。从「四个常见词」 换到「从 2048 词表里抽出的十二个词」,攻击者的工作量就从几小时变成超过宇宙年龄,因为熵从 44 位变成了 128 位。 好记与熵是相互拉扯的:任何让你更容易回想起来的技巧,同样让词表更容易收录它。
4. 历史记录:扫币机器人
大约在 2013 到 2015 年间,脑钱包不只是「有风险」—— 它们被主动收割。自动化的扫币机器人在两头同时开工:
- 离线:哈希海量候选列表,一次性推导出地址并保存成集合。这是一次性成本,此后任何一笔未来入账都能被 瞬间匹配。
- 在线:监控每一个新块 —— 常常连内存池里还没被打包的交易也一并监控 —— 寻找付给这些地址的输出。 一旦出现,立刻用更高的手续费广播一笔花费,好让扫币者的交易先被确认。入账在几秒内被清空,而且在许多有记录的案例里, 资金甚至从未在受害者自己的钱包里形成过已确认余额。
这种现象也曾被学术界研究。在《The Bitcoin Brain Drain》(Vasek、Bonneau、Castellucci、Keith、Moore, Financial Cryptography 2016)中,作者扫描区块链寻找由口令推导出的地址,找到了数百个曾经收到过资金的地址,并报告其中 绝大多数已被攻击者清空;媒体报道该论文时给出的失窃总额约为 10.3 万美元。具体数字远不如这个模式重要: 有资金的脑钱包几乎无一例外地被清空,而且通常就在几分钟甚至几秒之内。
与此同时,那些有名到会出现在教程里的短语 —— 本页示例用的那句 XKCD 名言、名著与名曲的第一句、任何在论坛帖子里被 反复引用的句子 —— 早已被成千上万人推导过,也在多年前就被扫走了。公开一个脑钱包,等于把它捐出去。 结果面板里为示例短语显示的那个地址被转载过无数次;请把它当成已经作废,因为它确实是。
今天也许是真的。但这并不是你以为的那种防线。攻击者的列表不是固定的:它随每一次口令泄露、每一篇公开的脑钱包文章、 每一条社交媒体帖子而增长,而你的地址可以零成本地被永久监控。脑钱包不是一份保质期很长的秘密,而是一道挂着奖金的公开 挑战题,只要币还在,它就一直开着。
5. 一个设计正确的 KDF 做了什么
基于口令的密钥派生函数被设计成「对攻击者昂贵、对合法用户还可忍受」:
- 盐 —— 每个用户随机、与密文一起保存 —— 让预计算失去意义,并保证两个用同一口令的人得到不同密钥。
BIP39 使用确定性盐(
"mnemonic" ‖ passphrase),正是因为钱包必须可重新推导;安全性只能由单词的熵来承担。 - 迭代次数 成倍放大单次猜测的成本。从 1 提高到 2048,就令每次猜测贵 2048 倍;提高到两百万,暴力破解就慢 两百万倍。这个参数就是用来对抗 GPU 和 ASIC 的,也正因如此,「只哈希一次」的脑钱包毫无辩护余地:攻击者跑的是最便宜的 内循环。
- 内存硬度 打击的是并行硬件的经济学。GPU 之所以能塞进几千个 SHA-256 核心,是因为 SHA-256 只需要几十字节 状态;而 scrypt 与 Argon2id 每次猜测需要数兆字节,于是吞吐率问题从「原始哈希算力」变成了「内存带宽与内存容量」问题。 Argon2id(2015 年密码哈希竞赛冠军,标准化于 RFC 9106)在迭代次数之外还提供可调的内存与并行度参数。
但要特别注意:BIP39 只用了 2048 轮 PBKDF2。这不是一个强 KDF 设置,而且它本来也不打算是。BIP39 的安全性并不 依赖 KDF —— 它依赖单词所编码的 128–256 位熵,加上一个充当盐的可选 passphrase。这个教训可以推广: 既要选一个真正有熵的输入,也要用一个足够昂贵的 KDF;两者缺一不可。
6. 脑钱包 vs BIP39 助记词 vs 随机密钥
| 脑钱包 | BIP39 助记词 | 随机 256 位密钥 | |
|---|---|---|---|
| 熵的来源 | 人凭记忆想出来的一句话 | 密码学安全随机数,再编码成单词 | 密码学安全随机数或安全芯片 |
| 真实熵 | 最多几十位;若曾被公开则实际上为 0 | 128 位(12 词)……256 位(24 词) | 最多 256 位 |
| 密钥派生 | 单次无盐 SHA-256 —— 完全没有工作因子 | PBKDF2-HMAC-SHA512,2048 轮,以 passphrase 为盐 | 不需要 |
| 能否凭记忆恢复 | 能 —— 而这正是全部问题所在 | 能,前提是书面备份丢了 | 不能 —— 没有备份就等于全丢 |
| 能否安全使用 | 不能 | 能,前提是由可信软件生成且备份受保护 | 能,前提是有备份 |
| 每次猜测的暴力成本 | 约 1 次哈希 | 约 4,096 次哈希运算 | 无关紧要 —— 要猜 2²⁵⁶ 次 |
| 攻击者需要什么 | 一份词表加一个浏览器标签页 | 你的备份,或你软件里的漏洞 | 你的备份,或你硬件里的漏洞 |
7. 实例演算:那句 XKCD 名言
输入框里的示例正是 XKCD 第 936 话中那句著名的四词句子,下面是上方表单为它算出的真实值 —— 可以在这里直接复现:
| 步骤 | 值 |
|---|---|
| 口令 | correct horse battery staple(28 个字符,28 个 UTF-8 字节) |
| 输入字节的十六进制 | 636f727265637420686f727365206261747465727920737461706c65 |
| 私钥 = 上述字节的 SHA-256 | c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a |
| WIF(压缩) | L3p8oAcQTtuokSCRHQ7i4MhjWc9zornvpJLfmg62sYpLRJF9woSu |
| 公钥(压缩) | 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 |
| hash160 | 79fbfc3f34e7745860d76137da68f362380c606c |
| P2PKH 地址 | 1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8 |
| P2SH-P2WPKH / P2WPKH / P2TR | 3KToBU4ykTWfjnu4kAUV1q8QosnxT61sbf / bc1q08alc0e5ua69scxhvyma568nvguqccrv4cc9n4 / bc1p3833qjvky7c2w3r7earqqwc377qeztadmfwjpwyy5srsch868lgs2v8tnw |
| 若那 28 个字符是随机生成的表面熵 | 28 × log₂(95) ≈ 184 位 |
| 这句短语的真实安全性 | 没有 —— 它存在于世上每一个脑钱包工具、教程和词表里 |
注意这个钱包看起来多么完整。这正是陷阱所在:它的输出与一个正常生成的钱包完全无法区分。地址、WIF、校验和里 没有任何东西能透露:它背后的密钥来自一句大半个互联网都已经哈希过的短语。区分一个安全钱包和这一个的唯一标准, 是密钥从何而来。
8. 常见错误
- 「它很长,所以很强。」 长度不是熵。一句 60 个字符的引语,真实熵可能还不如三个掷骰子选出的词。
- 「我加了符号和数字。」 每种破解工具都会自动套用这些规则;变形规则表是标准功能,不是防线。
- 「没人知道我那句话。」 如果它来自书、电影、歌词、论坛帖或你自己的社交媒体,那总有人 —— 或某个语料库 —— 知道。如果是你自己编的,那它遵循的是人类生成的模式,而这些模式同样被建模。
- 「区块链是匿名的,没人会找到它。」 事实恰好相反:区块链是一份永久公开、机器可读的清单,精确记录哪些 地址收到过钱,而扫币机器人会把它整个读完。
- 「我会永远记住它。」 记忆是人类最不可靠的存储介质。人会忘记短语、会对项目失去兴趣、会去世; 而币会永远留在那里。
- 把本页和内存硬 KDF 混为一谈。 在脑子里把哈希迭代 20 万次,和「为对抗 GPU 而设计的 KDF」完全不是 一回事 —— 况且如果输入只有 30 位熵,任何 KDF 都救不了它。
9. 速查表
| 项目 | 值 |
|---|---|
| 派生方式 | k = SHA-256(口令的 UTF-8 字节),一遍 |
| 盐 | 无 |
| 迭代次数 | 1 |
| 内存硬度 | 无 |
| 攻击者每次猜测成本 | 一次 SHA-256 求值(纳秒级) |
| 人类好记短语的熵 | 几十位;一旦被公开过实际上就是 0 |
| 入账后典型的被扫时间 | 几秒 |
| 推荐替代方案 | 硬件钱包生成的 BIP39 助记词 —— 见 BIP39 助记词 → BIP32 子私钥 |
| 你应该用它吗? | 不该。读懂它、理解它,并把它当作「不该怎么做」的示范。 |