Private Key Tools

私钥 → 非压缩 WIF

对载荷 0x80 ‖ k 做 Base58Check 编码,得到最初的 51 字符、以 5… 开头的钱包导入格式字符串 —— 老式纸钱包上印的就是它,它隐含非压缩公钥,因而也隐含那个遗留的 1… 地址。

64 位十六进制 = 32 字节。得到的是老式钱包对这把密钥会导出的 5… 字符串。准备清扫?请把两种 WIF 都算出来,并查清币在哪个地址上。
还没有输入

请在上方输入内容后点击「转换」。不知道填什么?点「填入示例」即可载入占位符里的演示数据。

技术原理详解

本页计算了什么

你输入一个 256 位私钥,本页给出它的非压缩 WIF —— 也就是最初的钱包导入 格式字符串:51 个字符,以 5 开头,内部不含压缩标志。2012 年年中之前的所有比特币备份都用这个 格式,印在老式纸钱包上的也还是它。

WIF非压缩 = Base58Check( 0x80 ‖ k )
私钥 k(32 B)→ 0x80 ‖ k(33 B)→ 两次 SHA-256→ 取前 4 字节→ 37 字节→ Base58→ 51 字符 WIF

把它和现代形式放在一起看:压缩 WIF 是 Base58Check(0x80 ‖ k ‖ 0x01) —— 多一个字节、多一个字符、校验和不同,隐含的地址也完全不同。

1. 最初的 WIF:那时公钥只有一种形状

第一个比特币客户端诞生时,公钥只有一种序列化形式:OpenSSL 不做任何选择就产出的那个 65 字节 04 ‖ X ‖ Y。没有压缩形式、没有标志位、也没有任何可选项。因此私钥需要携带的元数据只有一项 —— 它属于哪个网络(也就是哪种币)—— 此外什么都不需要。

由此得到的设计极其精简,而且一旦看懂就觉得理所当然:

最后用 Base58 编码,好让人能念、能敲,也避开形近字符。整个格式就这么多。名字「Wallet Import Format」 是后来才有的;编码本身从早期客户端就存在。请注意其中缺少什么:没有标志字节,因为当时没有任何东西 需要标记。这不是谁为老密钥设计的「遗留模式」—— 它就是原始格式,一字未改,而 2012 年的压缩形式是作为它的 扩展被造出来的。

为什么版本字节在这里也一样重要

0x80 不等于主网 P2PKH 地址开头的 0x00,也不等于非压缩公钥 标记的 0x04。同一条推导链上会出现三种不同的单字节头部。版本字节告诉钱包「这是一把主网私钥, 用的是最初的编码」,其余一切由此推出。

2. 去掉标志位为什么会改变载荷长度、首字符和校验和

同一把密钥的压缩 WIF 与非压缩 WIF,在载荷中只相差一个字节,而这一个字节带来四个可见的后果。

后果非压缩 WIF压缩 WIF
载荷长度33 字节(0x80 ‖ k)34 字节(0x80 ‖ k ‖ 0x01)
送进 Base58 的字节37 字节 = 296 比特38 字节 = 304 比特
字符串长度51 个字符52 个字符
首字符(主网)永远是 5K 或 L
校验和(演示密钥)b6f3d7f53a0a0417
隐含的地址(演示密钥)16kR3eis…WG2G146ZNjH7…2UqT

每一条都是机械推出来的:

3. 完整的字节布局

偏移(待编码输入)长度字段演示值说明
01 字节版本字节 0x8080主网私钥;测试网是 0xef
1 – 3232 字节私钥,大端序0824c31477…07a171ca固定 32 字节,保留前导零
—0 字节压缩标志 —— 不存在—正是这个「不存在」定义了非压缩形式
33 – 364 字节校验和b6f3d7f5SHA256d(第 0–32 字节) 的前 4 字节
37 字节33 字节载荷 + 4 字节校验和 → 51 个 Base58 字符

对演示密钥,校验和的计算过程值得完整看一遍,因为正是这一步把字符串与密钥绑定在一起:

阶段值
载荷(33 字节)800824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171ca
SHA256(载荷)0f5261d28f2887da16ac302c8f0593c885d57a538afd35f5067322b0e5f2fc96
SHA256(SHA256(载荷))b6f3d7f5f57bbbced3c64757bda8ac500a5fa6a346c278f65af7f84a865da824
校验和(前 4 字节)b6f3d7f5
交给 Base58 的最终 37 字节800824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171cab6f3d7f5

4. 为什么 5… 格式如今被视为历史遗留

2012 年并没有让这个格式失效。改变的是经济账与整个生态:

维度非压缩(5…)压缩(K…/L…)
花费时嵌入的公钥65 字节33 字节
典型 P2PKH scriptSig1 + 72 + 1 + 65 = 139 字节1 + 72 + 1 + 33 = 107 字节
每个输入多付的手续费比压缩形式多约 32 vbyte基准
SegWit(P2WPKH、P2SH-P2WPKH)不可能 —— witness v0 要求压缩公钥支持
Taproot(BIP340 / BIP86)不使用;Taproot 定义在 32 字节 x-only 公钥上标准输入
派生钱包支持只能作为孤立的遗留密钥导入所有 HD 钱包原生支持
还会被默认生成吗2012 年之后没有任何钱包这么做到处都是

所以 5… 密钥并不是坏的,只是又贵又别扭。它享受不到 SegWit 的费用折扣,无法支撑 Taproot 输出,而且在它余生的每一次花费中都要多付约 32 个虚拟字节的见证折扣后权重。钱包因此不再生产它,它所对应的 地址类型也被贴上了「遗留」标签 —— 这个词描述的是流行度,不是有效性。

5. 清扫(sweep)难题详解

这才是本页真正的核心。你有一张 2011 年印出来的老纸钱包,上面是一个 5… WIF 和一个 1… 地址,你想把币搬进现代钱包。可能发生三件事:

  1. 钱包直接拒绝这把密钥。 许多现代钱包 —— 尤其是基于输出描述符(descriptor)构建的, 以及某些硬件钱包的配套 App —— 只支持压缩密钥的导入账户。它们会回答「无效私钥」「不支持的密钥格式」, 或者干脆毫无反应。密钥本身没问题,只是软件里没有这条代码路径。
  2. 钱包收下了,却显示余额为零。 这是最危险也最常见的情况。钱包导入了那 32 字节密钥, 默认采用压缩形式(它唯一会推导的形式),算出 hash160(02/03‖X),盯着 146ZNjH7… 这类地址,然后什么也没找到 —— 因为你的币在非压缩地址上。你得到的结论等于 被告知这张纸钱包是空的。而且从钱包确实知道的那个地址清扫同样不可能,原因相同:它无法为一个 脚本中承诺了 65 字节公钥的输出签名。
  3. 钱包正确接受。 它把这把密钥当作「遗留密钥」账户导入,推导非压缩地址、监控它, 并用 65 字节公钥签名花费。有些钱包做得完全正确;这个功能通常叫「导入遗留密钥」 「清扫纸钱包」或「导入非压缩密钥」。
余额为零不等于币没了

第 2 种情况就是人们口中所说的「我的比特币不见了」。它几乎从来不是真的。你手上的私钥依然控制着那个 非压缩地址,你只是需要能由它推导非压缩公钥的软件。在采取任何激烈措施之前,先把情况查清楚:从密钥算出 非压缩地址(本页与私钥 → P2PKH 非压缩地址都会算),再到区块浏览器上查这个 确切地址。如果那里有币,就使用提供遗留密钥或纸钱包清扫功能的钱包/工具,用一笔交易把全部余额转到现代钱包 里的新地址上。

第 2 种情况还有个近亲陷阱:某个钱包接受了 5… 密钥,却悄悄把它「升级」,把 压缩地址当成你的新收款地址。如果你随后往那个压缩地址转币,你纸钱包上的旧余额和新余额就 落在两个不同地址上,而下次打开的钱包可能只监控其中一个。往任何地址转币之前,永远先确认钱包显示的地址 与你的预期是否一致。

6. 怎么判断币到底在哪种形式上

WIF 的首字符告诉你的是导出者的意图,而不是别人往哪里付过款。这是两个不同的问题, 而只有链上数据能回答第二个。

你手上有什么它能告诉你什么该去查什么
以 5 开头的 WIF导出者意图是非法压缩形式 —— 它的校验和与长度都印证了这一点先查非压缩地址,也查一下压缩地址,以防有人往那里付过款
以 K 或 L 开头的 WIF意图是压缩形式先查压缩地址,非压缩地址作为备用
以 1 开头的地址只能说明它是主网 P2PKH 地址 —— 两种形式都会产生 1… 地址用密钥把两个地址都算出来,与手上这个逐字比对
裸十六进制私钥关于编码,什么也说明不了两个地址都查;币在哪一个,就必须用哪一种形式去花
一个空纸钱包地址币已被转走,或从未到账由同一把密钥推出的另一个地址,以及交易历史

两条实用经验:(a) 纸钱包上印的地址与印的密钥,形式上几乎总是一致的 —— 5… 密钥配的是由 65 字节公钥构造的地址;(b) 当恢复结果看起来是空的,绝不要凭一个地址下结论。把两种都推出来、两个都查, 然后再决定。

7. 用真实演示数据演算一遍

以下全部是输入框里那个示例私钥的真实输出:

项目值
私钥 k0824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171ca
载荷 0x80 ‖ k(33 字节)800824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171ca
SHA256(SHA256(载荷))b6f3d7f5f57bbbced3c64757bda8ac500a5fa6a346c278f65af7f84a865da824
校验和b6f3d7f5
非压缩 WIF5HssbguBnjbaUVZCsH9YuzUG7T4vYQf51iiodi4izdVy6aVNekU
长度 / 首字符51 个字符,以 5 开头
非压缩公钥04ff812e26116a9aa140abe629e7f8a38401653caf925119def59ed3758c67ee808f49cde13c7ffd64f1d730bf87a743a578eda4971ddac4a08118160732b424ae
它的 hash1603f0e966dc089c611a9c1d03bd4f69ea53b0223f9
隐含的 P2PKH 地址16kR3eiswUY6tmGnxZhwQmW6LAvTLGWG2G
对照:同一把密钥的压缩 WIFKwVYL77Lcs1ckM39NvGjrtfKhU4KKdR2iB9Wq2FSMN6rbGK5tVqG(52 个字符,以 K 开头)
对照:压缩地址146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT
测试网非压缩 WIF91eWBRijNxfiSZ4VVd3Tnb2Dm7RdhaCGMfakiLRELNF1saLqhym
测试网非压缩地址mmGNLhorkVyMfskQg8gKEgiRCAXAGnxeBv

地址就是对那 65 字节密钥套用同一套 Base58Check 配方得到的,所以它自己的载荷也能列出来: 版本 00、hash160 3f0e966dc089c611a9c1d03bd4f69ea53b0223f9、校验和 3b0b7cbd,以及 34 个字符的结果 16kR3eiswUY6tmGnxZhwQmW6LAvTLGWG2G。

8. 往返验证

本页会用 Btc::wifDecode() 解码自己的输出,并在结果面板里显示还原出的每一个字段,让你看清 没有任何东西丢失或被凭空造出来:原始 32 字节密钥、为 false 的压缩标志、版本字节 80、主网、有效的 b6f3d7f5 校验和,以及 33 字节载荷。注意解码规则有多简洁 —— 并不存在一个显式的「非压缩标记」字节,载荷的长度本身就是标记:33 字节表示非压缩,34 字节且以 0x01 结尾表示压缩,其它长度一律拒绝。

9. 压缩 WIF 与非压缩 WIF 对照

非压缩 WIF(本页)压缩 WIF
公式Base58Check(0x80 ‖ k)Base58Check(0x80 ‖ k ‖ 0x01)
载荷 / 总字节33 B / 37 B34 B / 38 B
字符数5152
首字符(主网/测试网)5/9K 或 L/c
引入时间2009 年最初的客户端Bitcoin 0.6.0,2012 年 3 月
隐含的公钥04 ‖ X ‖ Y,65 字节02/03 ‖ X,33 字节
隐含的地址(演示密钥)16kR3eis…WG2G146ZNjH7…2UqT
能否用于 SegWit / Taproot不能可以
费用影响每个输入多约 32 vbyte基准
典型出现场合老纸钱包、2012 年前的备份所有现代导出

10. 安全须知

11. 常见错误

12. 速查表

项目值
编码方式Base58Check:载荷 ‖ SHA256d(载荷) 的前 4 字节
载荷0x80 ‖ k(32 B) —— 没有压缩标志
载荷 / 编码长度33 B / 37 B
输出51 个 Base58 字符,首字符 5(主网)
测试网变体0xef ‖ k,首字符 9
隐含的公钥65 字节,04 ‖ X ‖ Y
隐含的地址由 hash160(04‖X‖Y) 得到的 P2PKH
靠什么解码仅凭载荷长度(33 = 非压缩,34 且带 0x01 = 压缩)
可逆吗可以 —— 32 字节密钥被精确还原
链上仍然有效吗在旧式 P2PKH 脚本中有效