私钥

私钥就是一个随机选出的数字而已。一个比特币地址中的所有资金的控制取决于相应私钥的所有权和控制权。
比特币私钥只是一个数字。你可以用硬币、铅笔和纸来随机生成你的私钥:掷硬币256次,用纸和笔记录正反面并转换为0和1,随机得到的256位二进制数字可作为比特币钱包的私钥。该私钥可进一步生成公钥。
从一个随机数生成私钥
生成密钥的第一步也是最重要的一步,是要找到足够安全的熵源,即随机性来源。生成一个比特币私钥在本质上与“在1 到2^256之间选一个数字”无异。只要选取的结果是不可预测或不可重复的,那么选取数字的具体方法并不重要。比特币软件使用操作系统底层的随机数生成器来产生256位的熵(随机性)。通常情况下,操作系统随机数生成器由人工的随机源进行初始化,这就是为什么也可能需要不停晃动鼠标几秒钟。
更准确地说,私钥可以是1和n-1之间的任何数字,其中n是一个常数(n=1.158 * 10^77, 略小于2^256),并被定义为由比特币所使用的椭圆曲线的阶(见椭圆曲线密码学解释)。要生成这样的一个私钥,我们随机选择一个256位的数字,并检查它是否小于n-1。从编程的角度来看,一般是通过在一个密码学安全的随机源中取出一长串随机字节,对其使用SHA256哈希算法进行运算,这样就可以方便地产生一个256位的数字。如果运算结果小于n-1,我们就有了一个合适的私钥。否则,我们就用另一个随机数再重复一次。
私钥以 Base58校验和编码格式显示,这种私钥格式被称为钱包导入格式(WIF,Wallet Import Format)
以下是一个随机生成的私钥(k),以十六进制格式表示(256位的二进制数,以64位十六进制数显示,每个十六进制数占4位):
1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
提示比特币私钥空间的大小是2^256, 这是一个非常大的数字。用十进制表示的话,大约是10^77, 而可见宇宙被估计只含有10^80个原子。

公钥

通过椭圆曲线乘法可以从私钥计算得到公钥,这是不可逆转的过程:K = k * G 。其中k是私钥,G是被称为生成点的常数点,而K是所得公钥。其反向运算,被称为“寻找离散对数”——已知公钥K来求出私钥k——是非常困难的,就像去试验所有可能的k值,即暴力搜索。在演示如何从私钥生成公钥之前,我们先稍微详细学习下椭圆曲线密码学。
提示椭圆曲线乘法是密码学家称之为“陷阱门”功能的一种函数:在一个方向(乘法)很容易做,而不可能在相反的方向(除法)做。 私钥的所有者可以容易地创建公钥,然后与世界共享,知道没有人可以从公钥中反转函数并计算出私钥。 这个数学技巧成为证明比特币资金所有权的不可伪造和安全的数字签名的基础。

地址

比特币地址是一个由数字和字母组成的字符串,可以与任何想给你比特币的人分享。由公钥(一个同样由数字和字母组 成的字符串)生成的比特币地址以数字“1”开头。在交易中,比特币地址通常以收款方出现。下面是一个比特币地址的例子:
1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
比特币地址可由公钥经过单向的加密哈希算法得到。哈希算法是一种单向函数,接收任意长度的输入产生指纹或哈希。加密哈希函数在比特币中被广泛使用 :比特币地址、脚本地址以及在挖矿中的工作量证明算法。由公钥生成比特币地址时使用的算法是Secure Hash Algorithm (SHA)和the RACE Integ rity Primitives Evaluation Message Digest (RIPEMD),具体地说是SHA256和RIPEMD160。
以公钥 K 为输入,计算其SHA256哈希值,并以此结果计算RIPEMD160 哈希值,得到一个长度为160位(20字节)的数字:
A = RIPEMD160(SHA256(K))
公式中,K是公钥,A是生成的比特币地址。
通常用户见到的比特币地址是经过“Base58Check”编码的(参见“Base58和Base58Check编码”一节),这种编码 使用了58个字符(一种Base58数字系统)和校验码,提高了可读性、避免歧义并有效防止了在地址转录和输入中产生 的错误。Base58Check编码也被用于比特币的其它地方,例如比特币地址、私钥、加密的密钥和脚本哈希中,用来提高可读性和录入的正确性。
地址

Base64与Base58编码

为了更简洁方便地表示长串的数字,使用更少的符号,许多计算机系统会使用一种以数字和字母组成的大于十进制的表示法。
Base64使用了26个小写字母、26个大写字母、10个数字以及两个符号(例如“+”和“/”),用于在电子邮件这样的基于文本的媒介中传输二进制数据。
Base64通常用于编码邮件中的附件。Base58 是一种基于文本的二进制编码格式,用在比特币和其它的加密货币中。这种编码格式不仅实现了数据压缩,保持了易读 性,还具有错误诊断功能。Base58是Base64编码格式的子集,同样使用大小写字母和10个数字,但舍弃了一些容易错 读和在特定字体中容易混淆的字符。具体地,Base58不含Base64中的0(数字0)、O(大写字母o)、l(小写字母 L)、I(大写字母i),以及“+”和“/”两个字符。简而言之,Base58就是由不包括(0,O,l,I)的大小写字母和数字组成。

Base58Check

为了增加防止打印和转录错误的安全性,Base58Check是一种常用在比特币中的Base58编码格式,比特币有内置的检查错误的编码。检验和是添加到正在编码的数据末端的额外4个字节。校验和是从编码的数据的哈希值中得到的,所以可以用来检测并避免转录和输入中产生的错误。使用Base58check编码时,解码软件会计算数据的校验和并和编码中自带的校验和进行对比。二者不匹配则表明有错误产生,那么这个Base58Check的数据就是无效的。一个错误比特币地址就不会被钱包软件认为是有效的地址,否则这种错误会造成资金的丢失。
为了将数据(数字)转换成Base58Check格式,首先我们要对数据添加一个称作“版本字节”的前缀,这个前缀用来识别编码的数据的类 型。例如,比特币地址的前缀是0(十六进制是0x00),而对私钥编码时前缀是128(十六进制是0x80)。 表4-1会列出一些常见版本的前缀。
接下来,我们计算“双哈希”校验和,意味着要对之前的结果(前缀和数据)运行两次SHA256哈希算法:
checksum = SHA256(SHA256(prefix+data))
在产生的长32个字节的哈希值(两次哈希运算)中,我们只取前4个字节。这4个字节就作为检验错误的代码或者校验和。校验码会添加到数据之后。
结果由三部分组成:前缀、数据和校验和。这个结果采用之前描述的Base58字母表编码。下图描述了Base58Check编 码的过程。
base58ckeck
Base58Check编码的比特币地址是以1开头的,而Base58Check编码的私钥WIF是以5开头的。表4-1展示了一些版本前缀和他们对应的Base58格式。
image

加密私钥(BIP0038)

私钥必须保密。私钥的机密性需求情况是,在实践中相当难以实现,因为该需求与同样重要的安全对象可用性相互矛盾。当你需要为了避免私钥丢失而存储备份时,会发现维护私钥私密性是一件相当困难的事情。
通过密码加密存有私钥的钱包可能要安全一点,但那个钱包也需要备份。有时,例如用户因为要升级或重装钱包软件,而需要把密钥从一个钱包转移到另一个。私钥备份也可能需要存储在纸张上(参见“后面纸钱包”一节)或者外部存储介质里,比如U盘。但如果一旦备份文件失窃或丢失呢?这些矛盾的安全目标推进了便携、方便、可以被众多不同钱包和比特币客户端理解的加密私钥标准BIP0038的出台(BIP-38详细可参见附录部分)。
BIP0038提出了一个通用标准,使用一个口令加密私钥并使用Base58Check对加密的私钥进行编码,这样加密的私钥就可以安全地保存在备份介质里,安全地在钱包间传输,保持密钥在任何可能被暴露情况下的安全性。这个加密标准使 用了AES,这个标准由NIST建立,并广泛应用于商业和军事应用的数据加密。
BIP0038加密方案是:输入一个比特币私钥,通常使用WIF编码过,base58chek字符串的前缀“5”。此外BIP0038加密方案需要一个长密码作为口令,通常由多个单词或一段复杂的数字字母字符串组成。BIP0038加密方案的结果是一个由 base58check编码过的加密私钥,前缀为6P。如果你看到一个6P开头的的密钥,这就意味着该密钥是被加密过,并需要一个口令来转换(解码)该密钥回到可被用在任何钱包WIF格式的私钥(前缀为5)。许多钱包APP现在能够识别 BIP0038加密过的私钥,会要求用户提供口令解码并导入密钥。第三方APP,诸如非常好用基于浏览器的Bit Address , 可以被用来解码BIP00038的密钥。
最通常使用BIP0038加密的密钥用例是纸钱包——一张纸张上备份私钥。只要用户选择了强口令,使用BIP0038加密的私钥的纸钱包就无比的安全,这也是一种很棒的比特币离线存储方式(也被称作“冷存储”)。
BIP0038加密私钥例子
image

P2SH (Pay-to-Script Hash)

正如我们所知,传统的比特币地址从数字1开头,来源于公钥,而公钥来源于私钥。虽然任何人都可以将比特币发送到 一个1开头的地址,但比特币只能在通过相应的私钥签名和公钥哈希值后才能消费。
以数字3开头的比特币地址是P2SH地址,有时被错误的称谓多重签名或多重签名地址。他们指定比特币交易中受益人为哈希的脚本,而不是公钥的所有者。这个特性在2012年1月由BIP0016引进,目前因为BIP0016提供了增加功能到地址本身的机会而被广泛的采纳。不同于P2PKH交易发送资金到传统1开头的比特币地址,资金被发送到3开头的地址时,需要的不仅仅是一个公钥的哈希值和一个私钥签名作为所有者证明。在创建地址的时候,这些要求会被指定在脚本中,所有对地址的输入都会被这些要求阻隔。