精通比特 - 第4章,高级密钥和地址
4.5 高級密鑰和地址
在以下部分中,我們將看到高級形式的密鑰和地址,諸如加密私鑰、腳本和多重簽名地址,靚號地址,和紙錢包。
4.5.1 加密私鑰(BIP0038)
私鑰必須保密。私鑰的機密性需求事實情況是,在實踐中相當難以實現(xiàn),因為該需求與同樣重要的安全對象可用性相互矛盾。當你需要為了避免私鑰丟失而存儲備份時,會發(fā)現(xiàn)維護私鑰私密性是一件相當困難的事情。通過密碼加密內(nèi)有私鑰的錢包可能要安全一點,但那個錢包也需要備份。有時,例如用戶因為要升級或重裝錢包軟件,而需要把密鑰從一個錢包轉(zhuǎn)移到另一個。私鑰備份也可能需要存儲在紙張上(參見“4.5.4 紙錢包”一節(jié))或者外部存儲介質(zhì)里,比如U盤。但如果一旦備份文件失竊或丟失呢?這些矛盾的安全目標推進了便攜、方便、可以被眾多不同錢包和比特幣客戶端理解的加密私鑰標準BIP0038的出臺。
BIP0038提出了一個通用標準,使用一個口令加密私鑰并使用Base58Check對加密的私鑰進行編碼,這樣加密的私鑰就可以安全地保存在備份介質(zhì)里,安全地在錢包間傳輸,保持密鑰在任何可能被暴露情況下的安全性。這個加密標準使用了AES,這個標準由NIST建立,并廣泛應(yīng)用于商業(yè)和軍事應(yīng)用的數(shù)據(jù)加密。
BIP0038加密方案是:輸入一個比特幣私鑰,通常使用WIF編碼過,base58chek字符串的前綴“5”。此外BIP0038加密方案需要一個長密碼作為口令,通常由多個單詞或一段復雜的數(shù)字字母字符串組成。BIP0038加密方案的結(jié)果是一個由base58check編碼過的加密私鑰,前綴為6P。如果你看到一個6P開頭的的密鑰,這就意味著該密鑰是被加密過,并需要一個口令來轉(zhuǎn)換(解碼)該密鑰回到可被用在任何錢包WIT格式的私鑰(前綴為5)。許多錢包APP現(xiàn)在能夠識別BIP0038加密過的私鑰,會要求用戶提供口令解碼并導入密鑰。第三方APP,諸如非常好用基于瀏覽器的Bit Address,可以被用來解碼BIP00038的密鑰。
最通常使用BIP0038加密的密鑰用例是紙錢包——一張紙張上備份私鑰。只要用戶選擇了強口令,使用BIP0038加密的私鑰紙錢包就無比的安全,是一種很棒的線下比特幣存儲途徑(也被稱作“冷庫”)。
在bitaddress.org上測試表4-10中加密密鑰,看看你如何得到輸入口令的加密密鑰。
表4-10 BIP0038加密私鑰例子
| 密碼 | MyTestPassphrase |
| 加密私鑰(BIP0038) | 6PRTHL6mWa48xSopbU1cKrVjpKbBZxcLRRCdctLJ3z5yxE87MobKoXdTsJ |
4.5.2 P2SH (Pay-to-Script Hash)和多重簽名地址
正如我們所知,傳統(tǒng)的比特幣地址從數(shù)字1開頭,來源于公鑰,而公鑰來源于私鑰。雖然任何人都可以將比特幣發(fā)送到一個1開頭的地址,但比特幣只能在通過相應(yīng)的私鑰簽名和公鑰哈希值后才能消費。
以數(shù)字3開頭的比特幣地址是P2SH地址,有時被錯誤的稱謂多重簽名或多重簽名地址。他們指定比特幣交易中受益人作為哈希的腳本,而不是公鑰的所有者。這個特性在2012年1月由BIP0016引進,目前因為BIP0016提供了增加功能到地址本身的機會而被廣泛的采納。不同于發(fā)送資金到傳統(tǒng)1開頭的比特幣地址的交易,也被稱為P2PKH,資金被發(fā)送到3開頭的地址時,不僅僅需要一個公鑰的哈希值,同時也需要一個私鑰簽名作為所有者證明。在創(chuàng)建地址的時候,這些要求會被定義在腳本中,所有對地址的輸入都會被這些要求阻隔。
一個P2SH地址從事務(wù)腳本中創(chuàng)建,它定義誰能消耗這個事務(wù)輸出。(132頁“P2SH(Pay-to-Script-Hash)”一節(jié)對此有詳細的介紹)編碼一個P2SH地址涉及使用一個在創(chuàng)建比特幣地址用到過的雙重哈希函數(shù),并且只能應(yīng)用在腳本而不是公鑰:
script hash = RIPEMD160(SHA256(script))腳本哈希的結(jié)果是由Base58Check編碼前綴為5的版本、編碼后得到開頭為3的編碼地址。一個P2SH地址例子是32M8ednmuyZ2zVbes4puqe44NZumgG92sM。
P2SH 不一定是多重簽名的交易。雖然P2SH地址通常都是代表多重簽名,但也可能是其他類型的交易腳本。
4.5.2.1 多重簽名地址和P2SH
目前,P2SH函數(shù)最常見的實現(xiàn)是用于多重簽名地址腳本。顧名思義,底層腳本需要多個簽名來證明所有權(quán),此后才能消費資金。設(shè)計比特幣多重簽名特性是需要從總共N個密鑰中需要M個簽名(也被稱為“閾值”),被稱為M-的-N的多簽名,其中M是等于或小于N。例如,第一章中提到的咖啡店主鮑勃使用多重簽名地址需要1-2簽名,一個是屬于他的密鑰和一個屬于他同伴的密鑰,以確保其中一方可以簽署度過一個事務(wù)鎖定輸出到這個地址。這類似于傳統(tǒng)的銀行中的一個“聯(lián)合賬戶”,其中任何一方配偶可以憑借單一簽名消費。或Gopesh, Bob雇傭的網(wǎng)頁設(shè)計師創(chuàng)立一個網(wǎng)站,可能為他的業(yè)務(wù)需要一個2-3的多簽名地址,確保沒有資金會被花費除非至少兩個業(yè)務(wù)合作伙伴簽署這筆交易。
我們將會在第五章節(jié)探索如何使用P2SH地址創(chuàng)建事務(wù)用來消費資金。
4.5.3 比特幣靚號地址
靚號地址包含了可讀信息的有效比特幣地址。例如,1LoveBPzzD72PUXLzCkYAtGFYmK5vYNR33就是包含了Base-58字母love的。靚號地址需要生成并通過數(shù)十億的候選私鑰測試,直到一個私鑰能生成具有所需圖案的比特幣地址。雖然有一些優(yōu)化過的靚號生成算法,該方法必須涉及隨機上選擇一個私鑰,生成公鑰,再生成比特幣地址,并檢查是否與所要的靚號圖案相匹配,重復數(shù)十億次,直到找到一個匹配。
一旦找到一個匹配所要圖案的靚號地址,來自這個靚號地址的私鑰可以和其他地址相同的方式被擁有者消費比特幣。靚號地址不比其他地址具有更多安全性。它們依靠和其他地址相同的ECC和SHA。你無法比任何別的地址更容易的獲得一個靚號圖案開頭的私鑰。
在第一章中,我們介紹了Eugenia,一位在菲律賓工作的兒童慈善總監(jiān)。我們假設(shè)Eugenia組織了一場比特幣募捐活動,并希望使用靚號比特幣地址來宣布這個募捐活動。Eugenia將會創(chuàng)造一個以1Kids開頭的靚號地址來促進兒童慈善募捐的活動。讓我們看看這個靚號地址如何被創(chuàng)建,這個靚號地址對Eugenia慈善募捐的安全性又意味著什么。
4.5.3.1 生成靚號地址
我們必須認識到使用來自Base58字母表中簡單符號來代表比特幣地址是非常重要的。搜索“1kids”開頭的圖案我們會發(fā)現(xiàn)從1Kids11111111111111111111111111111到1Kidszzzzzzzzzzzzzzzzzzzzzzzzzzzzz的地址。這些以“1kid”開頭的地址范圍中大約有58的29次方地址。表4-11顯示了這些有“1kids”前綴的地址。
表4-11 “1Kids”靚號的范圍
| To | 1Kidszzzzzzzzzzzzzzzzzzzzzzzzzzzzz |
我們把“1Kids”這個前綴當作數(shù)字,我們可以看看比特幣地址中這個前綴出現(xiàn)的頻率。如果是一臺普通性能的桌面電腦,沒有任何特殊的硬件,可以每秒發(fā)現(xiàn)大約10萬個密鑰。
表4-12 靚號的出現(xiàn)的頻率(1KidsCharity)以及生成所需時間
| 1 | 1K | 1/58 | < 1毫秒 |
| 2 | 1Ki | 1/3,364 | 50毫秒 |
| 3 | 1Kid | 1/(195*103) | < 2秒 |
| 4 | 1Kids | 1/(11*106) | 1分鐘 |
| 5 | 1KidsC | 1/(656*106) | 1小時 |
| 6 | 1KidsCh | 1/(38*109) | 2天 |
| 7 | 1KidsCha | 1/(2.2*1012) | 3–4 月 |
| 8 | 1KidsChar | 1/(128*1012) | 13–18年 |
| 9 | 1KidsChari | 1/(7*1015) | 800年 |
| 10 | 1KidsCharit | 1/(400*1015) | 46,000年 |
| 11 | 1KidsCharity | 1/(23*1018) | 250萬年 |
正如你所見,Eugenia將不會很快地創(chuàng)建出以“1KidsCharity”開頭的靚號地址,即使她有數(shù)千臺的電腦同時進行運算。每增加一個字符就會增加58倍的計算難度。超過七個字符的搜索模式通常需要專用的硬件才能被找出,譬如用戶定制的具有多圖形處理單元(GPU)的桌面級設(shè)備。那些通常是無法繼續(xù)在比特幣挖礦中盈利的鉆機,被重新賦予了尋找靚號地址的任務(wù)。用GPU系統(tǒng)搜索靚號的速度比用通用CPU要快很多個量級。
另一種尋找靚號地址的方法是將工作外包給一個礦池里的靚號礦工們,如靚號礦池中的礦池。一個礦池是一種允許那些GPU硬件通過為他人尋找靚號地址來獲得比特幣的服務(wù)。對小額的賬單,Eugenia可以外包搜索模式為7個字符靚號地址尋找工作,在幾個小時內(nèi)就可以得到結(jié)果,而不必用一個CPU搜索上幾個月才得到結(jié)果。
生成一個靚號地址是一項通過蠻力的過程:嘗試一個隨機密鑰,檢查結(jié)果地址是否和所需的圖案想匹配,重復這個過程直到成功找到為止。例4-8是個靚號礦工的例子,用C++程序來尋找靚號地址。這個例子運用到了我們在56頁“其他替代客戶端、資料庫、工具包”一節(jié)介紹過的libbitcoin庫。
例4-8 靚號挖掘程序
#include // The string we are searching forconst std::string search = "1kid";// Generate a random secret key. A random 32 bytes.bc::ec_secret random_secret(std::default_random_engine& engine); // Extract the Bitcoin address from an EC secret.std::string bitcoin_address(const bc::ec_secret& secret);// Case insensitive comparison with the search string.bool match_found(const std::string& address);int main() { std::random_device random; std::default_random_engine engine(random()); // Loop continuously... while (true) { // Generate a random secret. bc::ec_secret secret = random_secret(engine); // Get the address. std::string address = bitcoin_address(secret); // Does it match our search string? (1kid) if (match_found(address)) { // Success! std::cout << "Found vanity address! " << address << std::endl; std::cout << "Secret: " << bc::encode_hex(secret) << std::endl; return 0; } } // Should never reach here! return 0; }bc::ec_secret random_secret(std::default_random_engine& engine){ // Create new secret... bc::ec_secret secret; // Iterate through every byte setting a random value... for (uint8_t& byte: secret) byte = engine() % std::numeric_limits::max(); // Return result. return secret;}std::string bitcoin_address(const bc::ec_secret& secret) { // Convert secret to pubkey... bc::ec_point pubkey = bc::secret_to_public_key(secret); // Finally create address. bc::payment_address payaddr; bc::set_public_key(payaddr, pubkey); // Return encoded form. return payaddr.encoded(); }bool match_found(const std::string& address) { auto addr_it = address.begin(); // Loop through the search string comparing it to the lower case // character of the supplied address. for (auto it = search.begin(); it != search.end(); ++it, ++addr_it) if (*it != std::tolower(*addr_it)) return false; // Reached end of search string, so address matches. return true; }示例程序需要用C編譯器鏈接libbitcoin庫(此庫需要提前裝入該系統(tǒng))進行編譯。直接執(zhí)行vanity-miner的可執(zhí)行文件(不用參數(shù),參見例4-9),它就會嘗試碰撞以“1kid”開頭的比特幣地址。
例4-9 編譯并運行vanity-miner程序示例
$ # Compile the code with g++$ g++ -o vanity-miner vanity-miner.cpp $(pkg-config --cflags --libs libbitcoin) $ # Run the example$ ./vanity-minerFound vanity address! 1KiDzkG4MxmovZryZRj8tK81oQRhbZ46YTSecret: 57cc268a05f83a23ac9d930bc8565bac4e277055f4794cbd1a39e5e71c038f3f$ # Run it again for a different result$ ./vanity-minerFound vanity address! 1Kidxr3wsmMzzouwXibKfwTYs5Pau8TUFnSecret: 7f65bbbbe6d8caae74a0c6a0d2d7b5c6663d71b60337299a1a2cf34c04b2a623# Use "time" to see how long it takes to find a result$ time ./vanity-minerFound vanity address! 1KidPWhKgGRQWD5PP5TAnGfDyfWp5yceXMSecret: 2a802e7a53d8aa237cd059377b616d2bfcfa4b0140bc85fa008f2d3d4b225349real 0m8.868suser 0m8.828ssys 0m0.035s正如我們運行Unix命令time所測出的運行時間所示,示例代碼要花幾秒鐘來找出匹配“kid”三個字符模板的結(jié)果。讀者們可以在源代碼中改變search這一搜索模板,看一看如果是四個字符或者五個字符的搜索模板需要花多久時間!
4.5.3.2 靚號地址安全性
靚號地址既可以增加、也可以削弱安全措施,它們著實是一把雙刃劍。用于改善安全性時,一個獨特的地址使對手難以使用他們自己的地址替代你的地址,以欺騙你的顧客支付他們的賬單。不幸的是,靚號地址也可能使得任何人都能創(chuàng)建一個類似于隨機地址的地址,甚至另一個靚號地址,從而欺騙你的客戶。
Eugenia可以讓捐款人捐款到她宣布的一個隨機生成地址(例如:1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy)。或者她可以生成一個以“1Kids”開頭的靚號地址以顯得更獨特。
在這兩種情況下,使用單一固定地址(而不是每比捐款用一個獨立的動態(tài)地址)的風險之一是小偷有可能會黑進你的網(wǎng)站,用他自己的網(wǎng)址取代你的網(wǎng)址,從而將捐贈轉(zhuǎn)移給自己。如果你在不同的地方公布了你的捐款地址,你的用戶可以在付款之前直觀地檢查以確保這個地址跟在你的網(wǎng)站、郵件和傳單上看到的地址是同一個。在隨機地址1j7mdg5rbqyuhenydx39wvwk7fslpeoxzy的情況下,普通用戶可能會只檢查頭幾個字符“1j7mdg”,就認為地址匹配。使用靚號地址生成器,那些想通過替換類似地址來盜竊的人可以快速生成與前幾個字符相匹配的地址,如表4-13所示。
表4-13 生成匹配某隨機地址的多個靚號
| 4位字符匹配 | 1J7md1QqU4LpctBetHS2ZoyLV5d6dShhEy |
| 5位字符匹配 | 1J7mdgYqyNd4ya3UEcq31Q7sqRMXw2XZ6n |
| 6位字符匹配 | 1J7mdg5WxGENmwyJP9xuGhG5KRzu99BBCX |
那靚號地址會不會增加安全性?如果Eugenia生成1Kids33q44erFfpeXrmDSz7zEqG2FesZEN的靚號地址,用戶可能看到靚號圖案的字母和一些字符在上面,例如在地址部分中注明了1Kids33。這樣就會迫使攻擊者生成至少6個字母相匹配的的靚號地址(比之前多2個字符),就要花費比Eugenia多3364倍的靚號圖案。本質(zhì)上,Eugenia付出的努力(或者靚號池付出的)迫使攻擊者不得不生成更長的靚號圖案。如果Eugenia花錢請礦池生成8個字符的靚號地址,攻擊者將會被逼迫到10字符的境地,那將是個人電腦,甚至昂貴自定義靚號挖掘機或靚號池也無法生成。對Eugenia來說可承擔的起支出,對攻擊者來說則變成了無法承擔支出,特別是如果欺詐的回報不足以支付生成靚號地址所需的費用。
4.5.4 紙錢包
紙錢包是打印在紙張上的比特幣私鑰。有時紙錢包為了方面起見也包括對應(yīng)的比特幣地址,但這并非是必要的。因為地址可以從私鑰中導出。紙錢包是一個非常有效簡歷備份或者線下比特幣存儲方式,也是被稱為“冷錢包”。作為備份機制,一個紙錢包可以提供安全性,以防在電腦硬盤損壞、失竊或意外刪除的情況下造成密鑰的的丟失。作為一個冷存儲的機制,如果紙錢包密鑰在線下生成并永久不在電腦系統(tǒng)中存儲,他們在應(yīng)對黑客攻擊,鍵盤記錄器,或其他在線電腦欺騙更有安全性。
紙錢包有許多不同的形狀,大小,和外觀設(shè)計,但非常基本的原則是一個密鑰和一個地址打印在紙張上。表4-14展現(xiàn)了紙錢包最基本的形式。
表4-14 比特幣紙錢包的私鑰和公鑰的打印形式
| 私鑰(WIF) | 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn |
通過使用工具,就可以很容易地生成紙錢包,譬如使用bitaddress.org網(wǎng)站上的客戶端Javascript生成器。這個頁面包含所有必要的代碼,甚至在完全失去網(wǎng)絡(luò)連接的情況下,也可以生成密鑰和紙錢包。若要使用它,先將HTML頁面保存在本地磁盤或外部U盤。從Internet網(wǎng)絡(luò)斷開,從瀏覽器中打開文件。更方便的,使用一個原始操作系統(tǒng)啟動電腦,比如一個光盤啟動的Linux系統(tǒng)。任何在脫機情況下使用這個工具所生成的密鑰,都可以通過USB線在本地打印機上打印出來,從而制造了密鑰只存在紙張上而從未存儲在在線系統(tǒng)上的紙錢包。將這些紙錢包放置在防火容器內(nèi),發(fā)送比特幣到對應(yīng)的比特幣地址上,從而實現(xiàn)了一個簡單但非常有效的冷存儲解決方案。圖4-14展示了通過bitaddress.org 生成的紙錢包。
圖4-14 通過bitaddress.org 生成的普通紙錢包
這個簡單的紙錢包系統(tǒng)的不足之處是那些被打印下來的密鑰容易被盜竊。一個能夠獲取接近這些紙幣的小偷可以只需偷走紙幣或者用把紙幣上密鑰拍攝下來,就能獲得被這些密鑰加密過的比特幣的控制權(quán)。一個更復雜的紙錢包存儲系統(tǒng)使用BIP0038加密的私鑰。這些私鑰被打印在紙錢包上被所有者記住的口令保護起來。沒有口令,這些被加密過的密鑰也是毫無用處的。但它們?nèi)耘f要比用口令保護的錢包級別要高,因為這些密鑰從沒有在線過,必須從物理上從保險箱或者其他物理安全存儲中導出。圖4-15展示了通過bitaddress.org 生成的加密紙錢包。
圖4-15 通過bitaddress.org 生成的加密紙錢包。密碼是“test”。
雖然你可以多次存款到紙錢包中,但是你最好一次性提款,一次性提取里面所有的資金。因為如果你提取的金額少于其中的金額的話,會生成一個找零地址。并且,你所用的電腦可能被病毒感染,那么就有可能泄露私鑰。一次性提款可以減少私鑰泄露的風險,如果你所需的金額比較少,那么請把余額找零到另一個紙錢包中。
紙錢包有許多設(shè)計和大小,并有許多不同的特性。有些作為禮物送給他人,有季節(jié)性的主題,像圣誕節(jié)和新年主題。另外一些則是設(shè)計保存在銀行金庫或通過某種方式隱藏私鑰的保險箱內(nèi),或者用不透明的刮刮貼,或者折疊和防篡改的鋁箔膠粘密封。圖4-16至圖4-18展示了幾個不同安全和備份功能的紙錢包的例子。
圖4-16 通過bitcoinpaperwallet.com生成的、私鑰寫在折疊皮瓣上的紙錢包
圖4-17 通過bitcoinpaperwallet.com 生成的、私鑰被密封住的紙錢包
其他設(shè)計有密鑰和地址的額外副本,類似于票根形式的可以拆卸存根,讓你可以存儲多個副本以防火災(zāi)、洪水或其他自然災(zāi)害。
圖4-18 在備份“存根”上有多個私鑰副本的紙錢包
==目錄==
簡介前言
第1章 介紹
第2章 比特幣的原理
第3章 比特幣客戶端
第4章 密鑰、地址、錢包
第4章 高級密鑰和地址
第5章 交易
第6章 比特幣網(wǎng)絡(luò)
第7章 區(qū)塊鏈
第8章 挖礦與共識
第8章 區(qū)塊鏈分叉、礦池、共識攻擊
第9章 競爭幣、競爭塊鏈和應(yīng)用程序
第10章 比特幣安全
附錄1 交易腳本的操作符、常量和符號
附錄2 比特幣改進協(xié)議
附錄3 pycoin庫、ku程序和tx交易程序
附錄4 sx工具下一些的命令
總結(jié)
以上是生活随笔為你收集整理的精通比特 - 第4章,高级密钥和地址的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux系统可以使用ppt功能不,Li
- 下一篇: 趣味网站和软件分享,快来看看有没有你pi