为什么“正确的”预售密码会失败

参考 . 2014年预售 . 密码漏洞

为什么“正确的”预售密码会失败

数千名2014年以太坊预售持有者输入了他们确信无误的密码——但钱包却始终无法打开。密码通常是正确的,但字节数据却不匹配。本文根据原始预售代码以及以太坊基金会自身的调查结果,详细梳理了这一现象的成因。

参考 · 更新于 2026 年 7 月 · KeychainX — 自 2017 年起提供钱包恢复服务

本文旨在指导恢复对自身预售钱包访问权限。下文中的每条说明都描述了在从键盘输入到密钥派生函数的过程中,软件可能如何篡改了正确输入的密码。这些情况均不会削弱或破坏底层加密机制,该机制依然是安全的——恢复操作仅在您能准确无误地重现实际使用的密码时才有效。

预售如何对您的密码进行加密

根据pyethsaletool的标准参考实现,该流程非常简短:先使用PBKDF2-HMAC-SHA256 对您的密码进行 2,000 轮扩展(截断为 16 字节)以生成密钥;然后用该密钥通过 AES 解密encseed;最后将结果进行哈希处理以生成私钥,并将该私钥的地址与文件中的ethaddr进行比对。 只有正确的密码才能生成匹配的地址。这就是 hashcat 的16300 模式。

有三个误区值得澄清,因为恢复页面一直在重复这些说法:预售阶段并未使用 scrypt 算法(那是后来的 V3 密钥库,模式 15700);迭代次数被刻意设得很低(2,000),这正是使得候选密码扫描变得可行的原因;密码并非使用随机值进行加盐——密码会自行加盐。 正是最后这一点,导致输入的微小变化会产生截然不同的结果。

根本原因:创建与解密

几乎所有漏洞背后的共同原因。该钱包由2014年的浏览器JavaScript创建(采用UTF-16字符串和CryptoJS风格的字节处理方式),而如今则由现代软件(通常采用UTF-8)进行解密。 密钥派生过程会原样对密码的字节进行哈希处理。因此,如果您的密码包含任何非ASCII字符,2014年存储的字节可能与现代工具生成的字节不同——导致正确的密码被判定为错误。纯ASCII密码则不受影响;它们在不同编码下的字节序列完全一致。

编码与规范化错误

  • Unicode 规范化(NFC 与 NFD)——这是主要原因。同一个字符可以是一个码点(NFC:é= U+00E9),也可以是一个字母加上一个组合标记(NFD:e+ U+0301)。在许多情况下,macOS 会向应用程序提供 NFD 格式的文本;而 Linux 和 Windows 则使用 NFC 格式。如果文本以一种格式创建,却以另一种格式重新输入,就会出现问题。测试这四种形式(NFC、NFD、NFKC、NFKD)可以解决大部分问题。
  • UTF-8 与 Latin-1 及 UTF-16 字节分支的对比。浏览器对变音符的处理可能产生了 Latin-1 低字节或原始 UTF-16 单元,而非现代工具所预期的 UTF-8。
  • 由于“先创建后存储”路径中的解码错误导致的双重编码/乱码(例如,ä被转换为ä)。
  • 音译。用户以某种方式输入了某个国家/地区的特殊字符,但回忆起来时却用另一种方式:德语中的ä↔aeß↔ss;瑞典语中的å↔aa;挪威语中的ø↔o/oe;西班牙语中的ñ↔n,等等。
  • 同形异义字符替换。当启用西里尔字母或希腊字母布局时,屏幕上看起来像拉丁字母的字符(例如西里尔字母“а” 对应字母“a”)实际上具有完全不同的码点。

macOS 输入的怪癖

  • 智能引号和智能破折号。macOS 会自动将直引号‘ “替换为花括号引号 ‘’“”,并将破折号 –替换为 ——。密码看起来一样,但字节内容不同。
  • 死键“卡住的重音符号”。在 macOS 上,如果尖音符/变音符/重音符后的字母不是基础字母,则会输出该重音符号加上该字母——例如,记忆中的“café”可能已被存储为“caf´e”
  • 长按重音菜单以及大写锁定键的 ergonomics。重音选择器与大写锁定键保持开启状态(某些 Mac 上没有明显的 LED 指示灯)会导致产生用户从未意图的大写和小写以及重音变体。

键盘布局与区域设置

  • 全键盘布局重映射——这是该基金会自身调查中发现的最明显的单一机制。如果在输入或传输的瞬间,操作系统的输入语言不是英语,系统就会对按键进行重映射,因此输入到输入框中的字符并非键帽上显示的字符。
  • QWERTZ 键盘的 y/z 键错位以及在创建和重新输入过程中出现的其他布局交换。
  • Geth 控制台的非 ASCII 字符过滤问题。如果将预售钱包后续导入 Geth,在某些区域设置下,其控制台会无提示地过滤掉代码点大于 127 的字符——这可能导致包含特殊字符的密码被截断或清空。(这是一个与路径相关的 bug,并非 2014 年版浏览器的问题。)

条目、硬件及文件错误

  • 熵阶段的“小失误”。预售环节通过鼠标移动收集了种子熵,而在此步骤中,密码输入框并非始终处于禁用状态——在晃动鼠标时,一次无意的按键可能会在密码后附加一个用户从未打算输入且无法回忆起的字符。这一问题是预售环节用户体验(UX)特有的。
  • 粘贴时产生的空格和换行符(粘贴到字段中时捕获的开头/结尾空格,或\n/\r\n)。
  • 按键卡住或弹跳,导致意外出现重复字符。
  • 验证后截断/密码为空——该字段在通过表单检查后被编辑。
  • 重新加密的差异。将钱包导入 MyEtherWallet、Mist 或 Geth 时,系统会使用新的加密参数对其进行重新加密——其中一份可能能正常打开,而另一份则可能无法打开;此外,如果重新导入过程出现错误,该钱包可能将永久无法打开。请保留并测试每一份副本。
  • 下载中断/文件完整性问题。如果在网速较慢的情况下下载中断,可能会导致加密文件不完整;届时将无法通过任何密码对其进行解密。在投入任何精力之前,请先验证文件。

这对经济复苏意味着什么

实际结果令人鼓舞:如果你记得密码,恢复预售钱包主要就是对一个已知字符串的这些变换进行穷举——而不是去猜测数百万个密码。一个合理的顺序是:

  • 找出所有JSON文件的副本——预售方已通过电子邮件发送给您;请检查旧邮件、存储设备、云端备份以及旧设备。重新加密后的副本内容各不相同,因此副本越多,成功几率就越大。
  • 在花时间处理每个文件之前,先对其进行验证(确保 JSON 格式正确、encseed长度合理)。
  • 请检查您的密码管理器中是否有任何2014年的条目提及以太坊众筹——并查看其密码历史记录,因为存储的值可能后来被修改过。
  • 请将您选定的最佳候选方案逐一应用于上述各种编码和输入习惯的变体中,并根据您当时使用的操作系统和键盘进行匹配。

如果文件本身已经丢失,那谁也帮不上忙——但如果你还保留着它,成功率远比大多数持有者想象的要高。这就是我们所从事的工作;请参阅我们的以太坊预售恢复指南

来源

本目录的内容综合自一手资料而非主观意见:包括标准的ethereum/pyethsaletool参考实现和预售前端(ethereum/www);以太坊基金会自身对“密码错误”问题的调查(Mist 问题 #3513 讨论串及相关报告); go-ethereum 项目中关于编码和控制台输入处理的问题;hashcat的 16300 模式实现;以及 John the Ripper 的ethereum2john 工具。上述行为已在上述资料中得到记录,并在被锁定账户持有者的陈述中有所体现。

常见问题

为什么我输入的正确的以太坊预售密码无法使用?

这几乎总是因为字节发生了变化,而不是密码本身。该钱包最初由2014年的浏览器JavaScript进行加密,如今则由现代软件解密;任何非ASCII字符(如变音符、重音符号)存储时使用的字节可能与现代工具生成的字节不同。密码本身是正确的,只是编码方式不同。纯ASCII密码不会出现这种情况。

预售密码验证失败的最常见原因是什么?

Unicode 规范化:同一个可见字符可以是一个码点(NFC),也可以是一个字母加一个组合标记(NFD)。macOS 通常向应用程序提供 NFD 文本,而 Linux 和 Windows 则使用 NFC,因此在一个系统上创建的密码若在另一个系统上重新输入,其哈希值会不同。测试所有规范化形式可以解决许多此类问题。

恢复预售密码会破坏以太坊的加密机制吗?

不。这些技术只是重现了你的密码在从键盘输入到密钥派生函数的过程中,可能被软件如何篡改的情况。只有当某种变换能完全还原你实际使用的密码时,恢复才算成功。其底层的AES和PBKDF2算法仍然是安全的,从未被攻破。

恢复预售钱包需要哪些条件?

预售 JSON 文件(包含 encseed 字段和您的 ethaddr)以及对密码的记忆。如果您有一个强有力的候选密码,恢复工作主要在于枚举该字符串的编码和输入特殊转换,而非靠猜测。如果文件本身丢失,则无法恢复。

一个无法解密的预售密码?

请将预售 JSON 文件以及您最可靠的密码记忆信息发送给我们——特别是您在 2014 年使用的操作系统、语言和键盘。我们将在 24 小时内给出客观评估,且仅在成功时才收取费用。

联系 KeychainX →