Private Key Tools

非压缩公钥 → hash160 → 地址

解析 65 字节的 04‖X‖Y 公钥,验证它确实落在 secp256k1 上,做哈希并构建传统 P2PKH 地址 —— 再把同一个点的压缩序列化形式摆在一旁对比,它对应的是完全不同的地址。

65 字节:04 ‖ X(32 字节)‖ Y(32 字节)。空格与换行会被忽略,大小写均可。这里不接受 33 字节压缩公钥或 32 字节 x-only 公钥 —— 请改用压缩公钥页。
还没有输入

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

技术原理详解

本页计算了什么

输入一个 65 字节的非压缩公钥 —— 以 04 开头的 130 位十六进制。输出:解析出的坐标、一次真实的 曲线方程校验、hash160、传统的 P2PKH 地址,以及并排对比的同一个点的压缩序列化形式,和它所产生的另一个 地址。

130 位十六进制→ 前缀 04→ X(32 字节)→ Y(32 字节)→ 曲线方程校验→ SHA-256 → RIPEMD-160→ hash160(20 字节)→ Base58Check(0x00 ‖ h)→ 1…

以及对照路径 —— 它只改变了第一个字节和整体长度:

同一个点→ 丢掉 Y,只留奇偶性→ 02/03 ‖ X(33 字节)→ 不同的 hash160→ 不同的地址

1. 04 ‖ X ‖ Y 的布局

公钥不是一个可以查表的数字,它是 secp256k1 曲线上的一个点,而 SEC1 标准规定了怎么把一个点写下来。 长的写法是:一个字节的标志位,后面把两个坐标按大端序完整写出。

字段字节十六进制位内容
前缀00–104 —— 「后面是一个非压缩点」
X1–322–65x 坐标,32 字节,大端序
Y33–6466–129y 坐标,32 字节,大端序
合计65130共 520 位的序列化点

大端序意味着最高有效字节在最前面:序列化中出现的前导零字节是有意义的,绝不能删掉。X 以 00a3… 开头的公钥,与 X 以 a3… 开头的是两个不同的点;一个会顺手裁剪前导零的解析器, 迟早会把钱送到不存在的地方。

SEC1 里的每个前缀字节都是对后续内容的承诺,而它的种类比多数人以为的要多:

前缀长度含义状态
0233 字节压缩:只有 x,y 为偶数标准
0333 字节压缩:只有 x,y 为奇数标准
0465 字节非压缩:x 与 y 都写出标准,历史遗留
0665 字节混合:x 与 y 都写出,且 y 为偶数已废弃
0765 字节混合:x 与 y 都写出,且 y 为奇数已废弃
(无)32 字节x-only,默认 y 为偶数(BIP340)仅用于 Taproot / Schnorr

2. 这个点真的在曲线上吗

只有当坐标满足曲线方程时,这串字节才是一个「点」。secp256k1 定义在模素数 p 的域上,所以这个 检验就是一次模运算比较:

Y² ≡ X³ + 7  (mod p)    其中 p = 0xFFFFFFFF…FEFFFFFC2F

两边相等,点就在曲线上,后续流程才可以继续。如果不相等,这份输入根本不是公钥,之后的所有计算都毫无意义: 对它做哈希会得到一个看起来很正常、却永远没人能花掉的地址,因为根本不存在与它对应的私钥。

本页会做这项校验,并对曲线外的输入直接给出可读的错误,而不是照样渲染结果。这不是礼貌问题,而是安全边界:

无效曲线攻击

如果程序不校验曲线方程就接受一个点,攻击者就可以提供一个位于另一条曲线上的点,而那条曲线的群阶要小 得多。用受害者的私钥标量去乘这个点,结果只会泄漏「私钥对该小阶取模」的信息 —— 但重复几次、换几个不同的 小阶,再用中国剩余定理,就能把完整的私钥拼回来。经典受害者是那些直接把对方送来的公钥用于 ECDH 的密钥 协商实现。对 secp256k1 来说余因子是 1,所以曲线内部没有小子群;真正的危险来自完全属于另一条曲线的 点。收下 65 字节、然后相信它的前缀,正是本页要避免的错误:先解析前缀,再验证方程,只有这两步都通过, 才会去哈希这个公钥。

3. 压缩与非压缩,是同一个点的两种写法

压缩不是有损的,也不是什么取巧手段。给定 X,方程

Y² = X³ + 7  (mod p)

恰好有两个解:Y 与 p − Y。因为 p 是奇数,p − Y ≡ −Y 会翻转最低位,所以这两个根奇偶性必然相反:一个为偶,一个为奇。于是「y 是奇数还是偶数」这 一个比特就足以唯一确定这个点,而 02/03 前缀存的就是这个比特。反方向则是实打实的 计算,但很便宜:由于 p ≡ 3 (mod 4),平方根有闭式解 Y = (X³ + 7)(p+1)/4 mod p,之后按需要的奇偶性决定是否取负即可。

所以两个方向的转换都是无损的。真正容易出错的是它的后果:这两种序列化是不同的字节串, 哈希出不同的值,因此同一个私钥会对应不同的地址。

非压缩压缩
长度65 字节 / 130 位十六进制33 字节 / 66 位十六进制
前缀04按 y 的奇偶性取 02 或 03
携带的信息完整的 X 与 YX 加一个奇偶性比特
hash160(演示公钥)3f0e966dc089c611a9c1d03bd4f69ea53b0223f921f57b6debcfc5b67182dfb4af1641f0a8189012
P2PKH 地址(演示公钥)16kR3eiswUY6tmGnxZhwQmW6LAvTLGWG2G146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT
花费时推送的字节数139(单输入、72 字节签名)107(同样的假设)
能用于 SegWit v0 花费吗不能 —— BIP143 要求压缩公钥可以
引入时间2009 年最初的客户端Bitcoin 0.6,2012 年

4. 混合型 06/07 前缀

「混合型」公钥长度是 65 字节 —— X 与 Y 都在 —— 但它的前缀声称自己知道 Y 的奇偶性:06 表示偶, 07 表示奇。换句话说,同一条信息被携带了两次。比特币核心从未产生过这种形式;它能存活下来,是因为 一些早期库接受它,而「被部分实现接受」正是一种传输格式最糟糕的状态。随之而来的是两类故障:

混合型公钥已被从建议标准中移除,现代钱包也都不再生成它。本页背后的库确实能识别 65 字节的 04、 06 与 07 输入,并对三者都做曲线方程校验 —— 但它不会把混合前缀与 Y 的奇偶性 交叉核对,所以一个 07 前缀配偶数 Y 的公钥也会被当作合法点接受。这种宽松处理正是该形式危险的原因: 同一串字节在不同库里会得到不同判断。因此本页直接拒绝 06/07,并要求你先把那一个字节 改成 04 再继续。改完之后,务必确认你得到的地址就是真正存放币的那个地址。

互操作性提醒

本页要求规范形式 04,如果你粘贴的是压缩公钥或混合型公钥,它会明确告诉你。若你手上有一个来自 老工具的 06/07 公钥,先把它改成 04(只改一个字节)再交给任何工具, 然后务必确认它算出的地址与真正存放币的那个地址一致。

5. 实例演算 —— 真实的演示公钥

步骤取值
输入(130 位十六进制)04ff812e26116a9aa140abe629e7f8a38401653caf925119def59ed3758c67ee808f49cde13c7ffd64f1d730bf87a743a578eda4971ddac4a08118160732b424ae
前缀04 → 非压缩,65 字节
Xff812e26116a9aa140abe629e7f8a38401653caf925119def59ed3758c67ee80
Y8f49cde13c7ffd64f1d730bf87a743a578eda4971ddac4a08118160732b424ae
Y 的奇偶性末位十六进制是 e → 偶数 → 压缩前缀 02,混合前缀 06
Y² mod p174ca53008928cd3c9c380e12c4b1dee0c5a0b6d851b1c472a58d744ca28c6dc
X³ + 7 mod p174ca53008928cd3c9c380e12c4b1dee0c5a0b6d851b1c472a58d744ca28c6dc —— 完全相同,点在曲线上
对 65 字节公钥做 hash1603f0e966dc089c611a9c1d03bd4f69ea53b0223f9
P2PKH 地址(非压缩)16kR3eiswUY6tmGnxZhwQmW6LAvTLGWG2G
压缩序列化02ff812e26116a9aa140abe629e7f8a38401653caf925119def59ed3758c67ee80
对 33 字节公钥做 hash16021f57b6debcfc5b67182dfb4af1641f0a8189012
P2PKH 地址(压缩)146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT
P2SH-P2WPKH(只能用压缩)3DZT76KyKyc5zkzvLugP8umgt4RPY4XPQw
P2WPKH(只能用压缩)bc1qy86hkm0telzmvuvzm76279jp7z5p3yqjnaerk6
x-only 32 字节形式(仅为参考地哈希一下)4d75c804c152bcc1e66a56cd6899f442b63dbf6c → 184a8MvQDPfePQPiVw3DUnAusPPvJmLGj7(这不是可花费的地址形式)

一个点、一个私钥,却对应六个不同的目标字符串。请留意最后一行:在同时处理 Taproot 公钥的代码里,顺手把 x-only 形式拿去哈希是很常见的事故,而它产生的是一个任何钱包都不会去看的地址。

6. 只读钱包:一个公钥能替你做到什么

本页除签名以外的所有内容,都只靠公钥就能算出来。这正是只读钱包(watch-only wallet)的 基础:把公钥(更常见的是 BIP32 扩展公钥)交给一台服务器或手机,它就能推导出你将来会用的每一个地址、跟踪每一笔 收款、算出你的余额 —— 而始终不持有任何可以花钱的秘密。

这很有用,但也必须看清楚它的另一面:

7. 它在推导链中的位置

8. 安全须知

9. 常见错误

10. 速查表

项目取值
布局04 ‖ X ‖ Y,65 字节,130 位十六进制
曲线校验Y² ≡ X³ + 7 (mod p)
域素数0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
压缩丢掉 Y,把奇偶性放进前缀:02 为偶,03 为奇
解压缩Y = (X³+7)(p+1)/4 mod p,再按奇偶性修正
由它得到的地址Base58Check(0x00 ‖ hash160(65 字节公钥))
混合前缀06/07 —— 已废弃,不要使用
兼容 SegWit 吗不兼容;witness v0 要求压缩公钥