公鑰與私鑰
比特幣的所有權(quán)是通過(guò)數(shù)字密鑰、比特幣地址和數(shù)字簽名來(lái)確定的。密鑰是成對(duì)出現(xiàn)的,由一個(gè)私鑰和一個(gè)公鑰所組成。公鑰就像銀行的帳號(hào),而私鑰就像控制賬戶(hù)的PIN碼或支票的簽名。
在比特幣交易的支付環(huán)節(jié),收件人的公鑰是通過(guò)其數(shù)字指紋代表的,稱(chēng)為比特幣地址,就像支票上的支付對(duì)象的名字 (即“收款方”)。一般情況下,比特幣地址由一個(gè)公鑰生成并對(duì)應(yīng)于這個(gè)公鑰。然而,并非所有比特幣地址都是公鑰; 他們也可以代表其他支付對(duì)象,譬如腳本。
加密
自從公鑰加密被發(fā)明之后,一些合適的數(shù)學(xué)函數(shù)被發(fā)現(xiàn),譬如:素?cái)?shù)冪和橢圓曲線乘法。這些數(shù)學(xué)函數(shù)都是不可逆的, 就是說(shuō)很容易向一個(gè)方向計(jì)算,但不可以向相反方向倒推?;谶@些數(shù)學(xué)函數(shù)的密碼學(xué),使得生成數(shù)字密鑰和不可偽造 的數(shù)字簽名成為可能。比特幣正是使用橢圓曲線乘法作為其公鑰加密的基礎(chǔ)。
公鑰和私鑰之間的數(shù)學(xué)關(guān)系,使得私鑰可用于生成特定消息的簽名。此簽名可以在不泄露私鑰的同時(shí)對(duì)公鑰進(jìn)行驗(yàn)證。
支付比特幣時(shí),比特幣的當(dāng)前所有者需要在交易中提交其公鑰和簽名(每次交易的簽名都不同,但均從同一個(gè)私鑰生 成)。比特幣網(wǎng)絡(luò)中的所有人都可以通過(guò)所提交的公鑰和簽名進(jìn)行驗(yàn)證,并確認(rèn)該交易是否有效,即確認(rèn)支付者在該時(shí)刻對(duì)所交易的比特幣擁有所有權(quán)。
私鑰和公鑰
一個(gè)比特幣錢(qián)包中包含一系列的密鑰對(duì),每個(gè)密鑰對(duì)包括一個(gè)私鑰和一個(gè)公鑰。私鑰(k)是一個(gè)數(shù)字,通常是隨機(jī)選出的。有了私鑰,我們就可以使用橢圓曲線乘法這個(gè)單向加密函數(shù)產(chǎn)生一個(gè)公鑰(K)。有了公鑰(K),我們就可以使 用一個(gè)單向加密哈希函數(shù)生成比特幣地址(A)。

為什么使用非對(duì)稱(chēng)加密(公鑰/私鑰)?
為什么在比特幣中使用非對(duì)稱(chēng)密碼術(shù)? 它不是用于“加密”(make secret)交易。 相反,非對(duì)稱(chēng)密碼學(xué)的有用屬性是生成數(shù)字簽名的能力。 可以將私鑰應(yīng)用于交易的數(shù)字指紋以產(chǎn)生數(shù)字簽名。 該簽名只能由知曉私鑰的人生成。 但是,訪問(wèn)公鑰和交易指紋的任何人都可以使用它們來(lái)驗(yàn)證簽名。 這種非對(duì)稱(chēng)密碼學(xué)的適用性使得任何人都可以驗(yàn)證每筆交易的每個(gè)簽名,同時(shí)確保只有私鑰的所有者可以產(chǎn)生有效的簽名。
私鑰
私鑰就是一個(gè)隨機(jī)選出的數(shù)字而已。一個(gè)比特幣地址中的所有資金的控制取決于相應(yīng)私鑰的所有權(quán)和控制權(quán)。
比特幣私鑰只是一個(gè)數(shù)字。你可以用硬幣、鉛筆和紙來(lái)隨機(jī)生成你的私鑰:擲硬幣256次,用紙和筆記錄正反面并轉(zhuǎn)換為0和1,隨機(jī)得到的256位二進(jìn)制數(shù)字可作為比特幣錢(qián)包的私鑰。該私鑰可進(jìn)一步生成公鑰。
從一個(gè)隨機(jī)數(shù)生成私鑰
生成密鑰的第一步也是最重要的一步,是要找到足夠安全的熵源,即隨機(jī)性來(lái)源。生成一個(gè)比特幣私鑰在本質(zhì)上與“在1 到2^256之間選一個(gè)數(shù)字”無(wú)異。只要選取的結(jié)果是不可預(yù)測(cè)或不可重復(fù)的,那么選取數(shù)字的具體方法并不重要。比特幣軟件使用操作系統(tǒng)底層的隨機(jī)數(shù)生成器來(lái)產(chǎn)生256位的熵(隨機(jī)性)。通常情況下,操作系統(tǒng)隨機(jī)數(shù)生成器由人工的隨機(jī)源進(jìn)行初始化,這就是為什么也可能需要不?;蝿?dòng)鼠標(biāo)幾秒鐘。
更準(zhǔn)確地說(shuō),私鑰可以是1和n-1之間的任何數(shù)字,其中n是一個(gè)常數(shù)(n=1.158 * 10^77, 略小于2^256),并被定義為由比特幣所使用的橢圓曲線的階(見(jiàn)橢圓曲線密碼學(xué)解釋?zhuān)?。要生成這樣的一個(gè)私鑰,我們隨機(jī)選擇一個(gè)256位的數(shù)字,并檢查它是否小于n-1。從編程的角度來(lái)看,一般是通過(guò)在一個(gè)密碼學(xué)安全的隨機(jī)源中取出一長(zhǎng)串隨機(jī)字節(jié),對(duì)其使用SHA256哈希算法進(jìn)行運(yùn)算,這樣就可以方便地產(chǎn)生一個(gè)256位的數(shù)字。如果運(yùn)算結(jié)果小于n-1,我們就有了一個(gè)合適的私鑰。否則,我們就用另一個(gè)隨機(jī)數(shù)再重復(fù)一次。
私鑰以 Base58校驗(yàn)和編碼格式顯示,這種私鑰格式被稱(chēng)為錢(qián)包導(dǎo)入格式(WIF,Wallet Import Format)
以下是一個(gè)隨機(jī)生成的私鑰(k),以十六進(jìn)制格式表示(256位的二進(jìn)制數(shù),以64位十六進(jìn)制數(shù)顯示,每個(gè)十六進(jìn)制數(shù)占4位):
1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
提示比特幣私鑰空間的大小是2^256, 這是一個(gè)非常大的數(shù)字。用十進(jìn)制表示的話,大約是10^77, 而可見(jiàn)宇宙被估計(jì)只含有10^80個(gè)原子。
公鑰
通過(guò)橢圓曲線乘法可以從私鑰計(jì)算得到公鑰,這是不可逆轉(zhuǎn)的過(guò)程:K = k * G 。其中k是私鑰,G是被稱(chēng)為生成點(diǎn)的常數(shù)點(diǎn),而K是所得公鑰。其反向運(yùn)算,被稱(chēng)為“尋找離散對(duì)數(shù)”——已知公鑰K來(lái)求出私鑰k——是非常困難的,就像去試驗(yàn)所有可能的k值,即暴力搜索。在演示如何從私鑰生成公鑰之前,我們先稍微詳細(xì)學(xué)習(xí)下橢圓曲線密碼學(xué)。
提示 橢圓曲線乘法是密碼學(xué)家稱(chēng)之為“陷阱門(mén)”功能的一種函數(shù):在一個(gè)方向(乘法)很容易做,而不可能在相反的方向(除法)做。 私鑰的所有者可以容易地創(chuàng)建公鑰,然后與世界共享,知道沒(méi)有人可以從公鑰中反轉(zhuǎn)函數(shù)并計(jì)算出私鑰。 這個(gè)數(shù)學(xué)技巧成為證明比特幣資金所有權(quán)的不可偽造和安全的數(shù)字簽名的基礎(chǔ)。
地址
比特幣地址是一個(gè)由數(shù)字和字母組成的字符串,可以與任何想給你比特幣的人分享。由公鑰(一個(gè)同樣由數(shù)字和字母組 成的字符串)生成的比特幣地址以數(shù)字“1”開(kāi)頭。在交易中,比特幣地址通常以收款方出現(xiàn)。下面是一個(gè)比特幣地址的例子:
1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
比特幣地址可由公鑰經(jīng)過(guò)單向的加密哈希算法得到。哈希算法是一種單向函數(shù),接收任意長(zhǎng)度的輸入產(chǎn)生指紋或哈希。加密哈希函數(shù)在比特幣中被廣泛使用 :比特幣地址、腳本地址以及在挖礦中的工作量證明算法。由公鑰生成比特幣地址時(shí)使用的算法是Secure Hash Algorithm (SHA)和the RACE Integ rity Primitives Evaluation Message Digest (RIPEMD),具體地說(shuō)是SHA256和RIPEMD160。
以公鑰 K 為輸入,計(jì)算其SHA256哈希值,并以此結(jié)果計(jì)算RIPEMD160 哈希值,得到一個(gè)長(zhǎng)度為160位(20字節(jié))的數(shù)字:
A = RIPEMD160(SHA256(K))
公式中,K是公鑰,A是生成的比特幣地址。
通常用戶(hù)見(jiàn)到的比特幣地址是經(jīng)過(guò)“Base58Check”編碼的(參見(jiàn)“Base58和Base58Check編碼”一節(jié)),這種編碼 使用了58個(gè)字符(一種Base58數(shù)字系統(tǒng))和校驗(yàn)碼,提高了可讀性、避免歧義并有效防止了在地址轉(zhuǎn)錄和輸入中產(chǎn)生 的錯(cuò)誤。Base58Check編碼也被用于比特幣的其它地方,例如比特幣地址、私鑰、加密的密鑰和腳本哈希中,用來(lái)提高可讀性和錄入的正確性。

Base64與Base58編碼
為了更簡(jiǎn)潔方便地表示長(zhǎng)串的數(shù)字,使用更少的符號(hào),許多計(jì)算機(jī)系統(tǒng)會(huì)使用一種以數(shù)字和字母組成的大于十進(jìn)制的表示法。
Base64使用了26個(gè)小寫(xiě)字母、26個(gè)大寫(xiě)字母、10個(gè)數(shù)字以及兩個(gè)符號(hào)(例 如“+”和“/”),用于在電子郵件這樣的基于文本的媒介中傳輸二進(jìn)制數(shù)據(jù)。
Base64通常用于編碼郵件中的附件。Base58 是一種基于文本的二進(jìn)制編碼格式,用在比特幣和其它的加密貨幣中。這種編碼格式不僅實(shí)現(xiàn)了數(shù)據(jù)壓縮,保持了易讀 性,還具有錯(cuò)誤診斷功能。Base58是Base64編碼格式的子集,同樣使用大小寫(xiě)字母和10個(gè)數(shù)字,但舍棄了一些容易錯(cuò) 讀和在特定字體中容易混淆的字符。具體地,Base58不含Base64中的0(數(shù)字0)、O(大寫(xiě)字母o)、l(小寫(xiě)字母 L)、I(大寫(xiě)字母i),以及“+”和“/”兩個(gè)字符。簡(jiǎn)而言之,Base58就是由不包括(0,O,l,I)的大小寫(xiě)字母和數(shù)字組成。
Base58Check
為了增加防止打印和轉(zhuǎn)錄錯(cuò)誤的安全性,Base58Check是一種常用在比特幣中的Base58編碼格式,比特幣有內(nèi)置的檢查錯(cuò)誤的編碼。檢驗(yàn)和是添加到正在編碼的數(shù)據(jù)末端的額外4個(gè)字節(jié)。校驗(yàn)和是從編碼的數(shù)據(jù)的哈希值中得到的,所以可以用來(lái)檢測(cè)并避免轉(zhuǎn)錄和輸入中產(chǎn)生的錯(cuò)誤。使用Base58check編碼時(shí),解碼軟件會(huì)計(jì)算數(shù)據(jù)的校驗(yàn)和并和編碼中自帶的校驗(yàn)和進(jìn)行對(duì)比。二者不匹配則表明有錯(cuò)誤產(chǎn)生,那么這個(gè)Base58Check的數(shù)據(jù)就是無(wú)效的。一個(gè)錯(cuò)誤比特幣地址就不會(huì)被錢(qián)包軟件認(rèn)為是有效的地址,否則這種錯(cuò)誤會(huì)造成資金的丟失。
為了將數(shù)據(jù)(數(shù)字)轉(zhuǎn)換成Base58Check格式,首先我們要對(duì)數(shù)據(jù)添加一個(gè)稱(chēng)作“版本字節(jié)”的前綴,這個(gè)前綴用來(lái)識(shí)別編碼的數(shù)據(jù)的類(lèi) 型。例如,比特幣地址的前綴是0(十六進(jìn)制是0x00),而對(duì)私鑰編碼時(shí)前綴是128(十六進(jìn)制是0x80)。 表4-1會(huì)列出一些常見(jiàn)版本的前綴。
接下來(lái),我們計(jì)算“雙哈希”校驗(yàn)和,意味著要對(duì)之前的結(jié)果(前綴和數(shù)據(jù))運(yùn)行兩次SHA256哈希算法:
checksum = SHA256(SHA256(prefix+data))
在產(chǎn)生的長(zhǎng)32個(gè)字節(jié)的哈希值(兩次哈希運(yùn)算)中,我們只取前4個(gè)字節(jié)。這4個(gè)字節(jié)就作為檢驗(yàn)錯(cuò)誤的代碼或者校驗(yàn)和。校驗(yàn)碼會(huì)添加到數(shù)據(jù)之后。
結(jié)果由三部分組成:前綴、數(shù)據(jù)和校驗(yàn)和。這個(gè)結(jié)果采用之前描述的Base58字母表編碼。下圖描述了Base58Check編 碼的過(guò)程。

Base58Check編碼的比特幣地址是以1開(kāi)頭的,而B(niǎo)ase58Check編碼的私鑰WIF是以5開(kāi)頭的。表4-1展示了一些版本前綴和他們對(duì)應(yīng)的Base58格式。

加密私鑰(BIP0038)
私鑰必須保密。私鑰的機(jī)密性需求情況是,在實(shí)踐中相當(dāng)難以實(shí)現(xiàn),因?yàn)樵撔枨笈c同樣重要的安全對(duì)象可用性相互矛盾。當(dāng)你需要為了避免私鑰丟失而存儲(chǔ)備份時(shí),會(huì)發(fā)現(xiàn)維護(hù)私鑰私密性是一件相當(dāng)困難的事情。
通過(guò)密碼加密存有私鑰的錢(qián)包可能要安全一點(diǎn),但那個(gè)錢(qián)包也需要備份。有時(shí),例如用戶(hù)因?yàn)橐?jí)或重裝錢(qián)包軟件,而需要把密鑰從一個(gè)錢(qián)包轉(zhuǎn)移到另一個(gè)。私鑰備份也可能需要存儲(chǔ)在紙張上(參見(jiàn)“后面紙錢(qián)包”一節(jié))或者外部存儲(chǔ)介質(zhì)里,比如U盤(pán)。但如果一旦備份文件失竊或丟失呢?這些矛盾的安全目標(biāo)推進(jìn)了便攜、方便、可以被眾多不同錢(qián)包和比特幣客戶(hù)端理解的加密私鑰標(biāo)準(zhǔn)BIP0038的出臺(tái)(BIP-38詳細(xì)可參見(jiàn)附錄部分)。
BIP0038提出了一個(gè)通用標(biāo)準(zhǔn),使用一個(gè)口令加密私鑰并使用Base58Check對(duì)加密的私鑰進(jìn)行編碼,這樣加密的私鑰就可以安全地保存在備份介質(zhì)里,安全地在錢(qián)包間傳輸,保持密鑰在任何可能被暴露情況下的安全性。這個(gè)加密標(biāo)準(zhǔn)使 用了AES,這個(gè)標(biāo)準(zhǔn)由NIST建立,并廣泛應(yīng)用于商業(yè)和軍事應(yīng)用的數(shù)據(jù)加密。
BIP0038加密方案是:輸入一個(gè)比特幣私鑰,通常使用WIF編碼過(guò),base58chek字符串的前綴“5”。此外BIP0038加密方案需要一個(gè)長(zhǎng)密碼作為口令,通常由多個(gè)單詞或一段復(fù)雜的數(shù)字字母字符串組成。BIP0038加密方案的結(jié)果是一個(gè)由 base58check編碼過(guò)的加密私鑰,前綴為6P。如果你看到一個(gè)6P開(kāi)頭的的密鑰,這就意味著該密鑰是被加密過(guò),并需要一個(gè)口令來(lái)轉(zhuǎn)換(解碼)該密鑰回到可被用在任何錢(qián)包WIF格式的私鑰(前綴為5)。許多錢(qián)包APP現(xiàn)在能夠識(shí)別 BIP0038加密過(guò)的私鑰,會(huì)要求用戶(hù)提供口令解碼并導(dǎo)入密鑰。第三方APP,諸如非常好用基于瀏覽器的Bit Address , 可以被用來(lái)解碼BIP00038的密鑰。
最通常使用BIP0038加密的密鑰用例是紙錢(qián)包——一張紙張上備份私鑰。只要用戶(hù)選擇了強(qiáng)口令,使用BIP0038加密的私鑰的紙錢(qián)包就無(wú)比的安全,這也是一種很棒的比特幣離線存儲(chǔ)方式(也被稱(chēng)作“冷存儲(chǔ)”)。
BIP0038加密私鑰例子

P2SH (Pay-to-Script Hash)
正如我們所知,傳統(tǒng)的比特幣地址從數(shù)字1開(kāi)頭,來(lái)源于公鑰,而公鑰來(lái)源于私鑰。雖然任何人都可以將比特幣發(fā)送到 一個(gè)1開(kāi)頭的地址,但比特幣只能在通過(guò)相應(yīng)的私鑰簽名和公鑰哈希值后才能消費(fèi)。
以數(shù)字3開(kāi)頭的比特幣地址是P2SH地址,有時(shí)被錯(cuò)誤的稱(chēng)謂多重簽名或多重簽名地址。他們指定比特幣交易中受益人為哈希的腳本,而不是公鑰的所有者。這個(gè)特性在2012年1月由BIP0016引進(jìn),目前因?yàn)锽IP0016提供了增加功能到地址本身的機(jī)會(huì)而被廣泛的采納。不同于P2PKH交易發(fā)送資金到傳統(tǒng)1開(kāi)頭的比特幣地址,資金被發(fā)送到3開(kāi)頭的地址時(shí),需要的不僅僅是一個(gè)公鑰的哈希值和一個(gè)私鑰簽名作為所有者證明。在創(chuàng)建地址的時(shí)候,這些要求會(huì)被指定在腳本中,所有對(duì)地址的輸入都會(huì)被這些要求阻隔。
一個(gè)P2SH地址從交易腳本中創(chuàng)建,它定義誰(shuí)能消耗這個(gè)交易輸出。編碼一個(gè)P2SH地址涉及使用一個(gè)在創(chuàng)建比特幣地址用到過(guò)的雙重哈希函數(shù),并且只能應(yīng)用在腳本而不是公鑰:
script hash = RIPEMD160(SHA256(script0))
簡(jiǎn)單理解就是轉(zhuǎn)賬的接收人不是一個(gè)公鑰地址,而是一個(gè)腳本,該腳本的輸入必須是指定的幾個(gè)交易發(fā)起者,簡(jiǎn)單例子就是多重簽名。
提示 P2SH 不一定是多重簽名的交易。雖然P2SH地址通常都是代表多重簽名,但也可能是編碼其他類(lèi)型的交易腳本。
多重簽名地址
目前,P2SH函數(shù)最常見(jiàn)的實(shí)現(xiàn)是多重簽名地址腳本。顧名思義,底層腳本需要多個(gè)簽名來(lái)證明所有權(quán),此后才能消費(fèi)資金。設(shè)計(jì)比特幣多重簽名特性是需要從總共N個(gè)密鑰中需要M個(gè)簽名(也被稱(chēng)為“閾值”),被稱(chēng)為M-N多簽名,其 中M是等于或小于N。例如,第一章中提到的咖啡店主Bob使用多重簽名地址需要1-2簽名,一個(gè)是屬于他的密鑰和一個(gè)屬于他同伴的密鑰,以確保其中一方可以簽署消費(fèi)一筆鎖定到這個(gè)地址的輸出。這類(lèi)似于傳統(tǒng)的銀行中的一個(gè)“聯(lián)合賬戶(hù)”,其中任何一方配偶可以單獨(dú)簽單消費(fèi)?;蚓拖馚ob雇傭的網(wǎng)頁(yè)設(shè)計(jì)師Gopesh, 創(chuàng)立一個(gè)網(wǎng)站,可能為他的業(yè)務(wù)需要一個(gè)2-3的多簽名地址,確保除非至少兩個(gè)業(yè)務(wù)合作伙伴簽署簽名交易才可以進(jìn)行支付消費(fèi)。
本文原文-密鑰與地址 http://book.8btc.com/books/6/masterbitcoin2cn/_book/ch04.html