# 比特币的私钥，公钥和地址是什么？

By [wabei](https://paragraph.com/@wabei-2) · 2022-09-11

---

在比特币中，经常出现三个词：`私钥，公钥和地址`。他们是什么意思呢？他们之间又有什么样的关系呢？搞清楚他们之间的关系和区别，是了解比特币的基础。

私钥
--

先说说私钥，一般我们看到的私钥是下面这样的一段字符串：

支持比特币协议的应用都可以正确把这段字符串转换成比特币的_私钥_，再转换出公钥，再得到一个地址，如果该地址上面有对应的比特币，就可以使用这个私钥花费上面的比特币。

*   私钥本质上是随机数
    
    私钥本质上是一个随机数，由32个_byte_组成的数组，1个_byte_等于8位二进制，一个二进制只有两个值0或者1。所以私钥的总数是将近2(8\*32)=2256个，但是有一些私钥并不能使用，他真实的大小是介于:`1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141`之间的数。这个数量已经超过了宇宙中原子的总数，想要遍历所有的私钥，耗尽整个太阳的能量也是不可能的。
    

我们所说的比特币私钥的是密码学上面安全的，并不是说不可能出现重复的私钥，而是说不可能通过遍历的方式找到某一个特定的私钥，或者通过其它的方式找，而不通过私钥就能花费地址上面的比特币，私钥的安全性是由数学上保证的。 私钥的总数量很大，但是私钥的生成是依赖随机数的，真正的随机是很难做到的，大部分私钥的生成都是依赖于`伪随机算法(PRNG)`。

> 伪随机是用函数生成随机数。它并不真正是随机的。只是一个比较近似真随机的随机数。

私钥生成的随机性就很重要的，密码学上安全的随机是指：

> 随机是不可预测的，随机的结果是不可遍历的，如果不是安全的随机数生成器，生成的私钥就有可能被别人碰撞到。不依赖随机生成的私钥就会大大的降低其生成的概率空间。

公钥和地址的生成都依赖私钥，所以我们只需要保存私钥即可，有了私钥就能生成公钥和地址，就能够花费对应地址上面的比特币。

*   私钥到字符串 上面提高的私钥字符串是按照一定的规律从32位byte数据格式化生成的,32个byte的数组是由256个0或者1组成的，如果显示出来，不仅仅是识别率不高，而且私钥太长。 因此私钥字符串就是对于原始的随机数进行一定的转换，转换为识别率高的形式，上面私钥的是对32个byte数组就做了`Base58`的转换.
    

> Base58是用于比特币中使用的一种独特的编码方式，主要用于产生Bitcoin的钱包地址和私钥。相比Base64，Base58不使用数字"0"，字母大写"O"，字母大写"I"，和字母小写"l"，以及"+"和"/"符号。这样做的主要原因是为了肉眼容易识别，在输入的时候不容易打错，

不过上面那段没有规律的字符串输入起来还是挺费劲的，当然也可以把私钥转换其他形式，比如以单词的形式(12或者24个单词)，脑钱包的形式,又或者自己记住的某一句话来生成私钥，注意脑钱包生成的私钥随机的安全性并不高。

我们看到的私钥除了以5开头的以外，还有以`L`和`K`开头的私钥，为什么会出现这样的情况呢？`5，L，K`又带代表什么呢？这就要说到公钥了。

公钥
--

比特币的根基是`椭圆曲线数字签名算法`:

> 椭圆曲线数字签名算法（ECDSA）是使用椭圆曲线密码（ECC）对数字签名算法（DSA）的模拟

`椭圆曲线加密法（ECC）`是一种公私钥加密技术:

> ECC以椭圆曲线理论为基础，利用椭圆曲线等式的性质来产生密钥，而不是采用传统的方法利用大质数的积来产生，其特点是：密钥长度小，安全性能高，整个数字签名耗时小。

DSA(DigitalSignature Standard)数字签名技术：

> 在DSA数字签名和认证中，发送者使用自己的私钥对文件或消息进行签名，接受者收到消息后使用发送者的公钥来验证签名的真实性。

这里明确了`私钥`用来`签名`，而`公钥`用来`验证签名`。 公钥是由私钥生成的，通过`椭圆曲线(ECPoint)`生成，一个私钥经过`椭圆曲线`变换之后能够得到公钥，公钥是一个65个byte数组，一般我们会看到这样的一个公钥：

> 04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235

显示出的公钥一般把byte数组是经过`hex（16进制）`的处理之后显示，不经过Base58的原因是： 公钥是用来验证私钥的签名，一般我们很少会看到公钥，使用私钥签名交易之后，会把自己的公钥一起和交易发送出去，这样对于一个完整的交易开说，他就使用交易里包含的公钥验证私钥的签名是否正确。 私钥和公钥是成对出现的，一个私钥签名的数据，只有对应的公钥才能对其进行验证，而地址也是从公钥生成的，这样就可以验证花费的交易是不是属于这个地址了！

*   回答下上面的问题为什么会出现5开头或者L,K开头的私钥？ 出现这种情况是因为公钥的不同格式而产生了不同的私钥格式，早期的比特币开发者没有使用压缩的公钥（椭圆曲线是对称的，知道了一半的信息就可以推导出来另外一半的信息了），因此只需要保存一般的公钥信息即可。压缩的公钥只有33个byte,而未压缩的公钥有65个byte。
    

> 私钥开头的第一位的不同，是用来区分该私钥使用的公钥是否支持压缩格式

压缩的公钥对比特币的意义很大，比特币是去中心化的`p2p加密货币`，每个节点都会拥有完整的交易记录，除了`coinbase`（挖矿得到的比特币）以外，每个交易都需要发送公钥，支持压缩格式的公钥，每个交易的数据就可以减少32个字节，这对整个比特币网络是非常有意义的,整个比特币网络的数据在传输和保存中都可以提高不少效率。

而对私钥进行Base58编码的时候，老版本未压缩公钥的私钥是33位byte数组，第一位存放私钥的`Version信息`，当前值为128，生成的Base58都是以5开头。

> 老版本未压缩私钥=Base58（version+32位随机数）

支持压缩公钥的私钥是34位，同样是第一位是version信息，它的值也是128，而多出来的一位是最后一个byte是用来存放`是否压缩信息的信息`，1就表示是支持`压缩格式的公钥`。经过Base58处理之后正好是L或者K开头

> 新版本私钥格式=Base58(version+32位随机数+是否支持压缩)

例子中的私钥不仅仅包含了32个byte数组的信息，还是私钥version的信息以及其公钥是否压缩的信息（通过位数和值来判断） 公钥是否压缩除了对私钥的显示有影响以外，还会对地址有影响。

地址
--

公钥太长了，所以就有更短一些的地址的概念，另一方面没有发送过交易的地址，并不想暴露自己的公钥，而地址是通过`摘要算法`生成的,不会暴露公钥的真实内容：

> 地址是由公钥产生的,地址长度为25byte,经过base58处理，地址未尾添加了4个字节的校验位。

我们看到的地址一般都是`Base58`编码处理的，地址的生成比较复杂，公钥到地址生成的过程是，先对公钥做一次`SHA256`(哈希算法)。

> sha-256-hash= SHA-256(public key)

再经过了`hash160`处理， hash160:`RIPEMD(PACE integrity Primitives Evaluation Message Digest)`是一种原始完整性校验消息摘要，160标准对应20字节:

> hash160=hash160(sha-256-hash)

对结果进行hash160处理可以得到一个20个byte的数组，在这个20位的byte数组前面再加上一个byte,这个byte就是地址的Version信息，地址的Version当前值为0，Version信息在比特币的`test网络`上会使用不同的值,比特币地址完成的表示就是：

> address=Base58(version+hash160(SHA-256(public key))+checksum)

checksum是用来对于比特币地址进行检验的，再得到的hash160中加入地址的version信息 ，再对该信息做两次`SHA-256`之后取前4位就是checksum:

> checksum=get\_front\_four( SHA-256(SHA-256(version+hash160)))

其中hash160是这个过程中最重要的信息，从这个值就可以到地址的前21位（第一位是version）和后面的checksum, 进而可以生成Base58格式的地址。而从Base58格式的地址中也可以得到hash160，也就是说hash160格式可以和Base58格式的地址互换。 私钥的不同对于地址有什么样的影响呢？ 前面已经说了:

> 一个随机数可以有一个压缩的公钥，和一个未压缩的公钥

而每个公钥都会生成一个地址，上面私钥其实可以有两个地址分别为：

> 1HZwkjkeaoZfTSaJxDw6aKkxp45agDiEzN（未压缩公钥） 1F3sAm6ZtwLAUnj7d38pGFxtP3RVEvtsbV (压缩公钥)

这两个地址都是这一个随机数生成的地址，每个地址上面的比特币都可以用这个随机数对应的私钥花费。目前大多数的应用默认都使用压缩格式的私钥。

*   总结 对于私钥，公钥和地址来说，`公钥`作为私钥到地址的中间桥梁，他在交易的验证是最关键的：
    
    > 对于一个交易的验证，公钥的作用：
    
    1.  公钥生成地址，验证发送交易的地址是否和该公钥生成的地址一致
        
    2.  公钥验证私钥的签名，用来验证该交易是否使用了正确的私钥签名
        
    3.  私钥生成公钥是成对出现，公钥可以生成对应的唯一地址，这样就能确认了该地址发送的交易是否使用了对应的私钥
        

本文转载至网络，出处如下：

作者：姜家志 链接：[https://www.jianshu.com/p/af6328cc693e](https://www.jianshu.com/p/af6328cc693e) 来源：简书 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。

---

*Originally published on [wabei](https://paragraph.com/@wabei-2/MAnPJ3fd7Ra9z34BGxNl)*
