钱包原理——助记词与公私钥
目前錢包分為兩種:
一種是非確定性(隨機(jī))的錢包,就是隨機(jī)生成多個(gè)私鑰,錢包管理這些私鑰。如果需要成千上萬(wàn)的地址,通過隨機(jī)的方式來(lái)生成私鑰,這就需要存儲(chǔ)那么多無(wú)規(guī)律的私鑰,這樣就很麻煩不好管理。
另一種是確定性(種子)的錢包,就是通過種子可以生成無(wú)數(shù)的私鑰,我們只需要記住種子就可以了。我們?cè)谑褂缅X包時(shí)記住的助記詞可以生成種子,只要我們保管好助記詞,我們的幣就能找回來(lái)。用一句話來(lái)解釋助記詞:它是私鑰的明文顯示。
主要流程
1、隨機(jī)生成128到258位的隨機(jī)數(shù),稱作熵;
2、熵經(jīng)過一定處理方法,生成助記詞;
3、助記詞經(jīng)過密鑰延伸函數(shù)PBKDF2,生成種子;
4、種子經(jīng)過HMAC-SHA512算法,生成母密鑰;
5、通過CKD(child key derivation)函數(shù),母密鑰生成眾多子密鑰。
從熵到助記詞
1、生成一個(gè)128到256位的數(shù)字,叫做熵,熵的長(zhǎng)度是32的整數(shù)倍,分別為 128, 160, 192, 224, 256,也就是我們私鑰的長(zhǎng)度。
2、熵通過SHA256哈希得到一個(gè)值,取前面的幾位(熵長(zhǎng)/32),稱為校驗(yàn)和, 所以校驗(yàn)和長(zhǎng)度可為 4,5,6,7,8 位。
3、校驗(yàn)和加入熵的末尾,組成一個(gè)新的序列。
4、將新序列以11位為一部分,與已經(jīng)預(yù)先定義2048個(gè)單詞的字典做對(duì)應(yīng)。
5、生成的有順序的單詞組就是助記詞。
從助記詞到種子
通過使用密鑰延伸函數(shù)PBKDF2,熵被用于導(dǎo)出較長(zhǎng)的(512位)種子。
PBKDF2的基本原理是通過一個(gè)偽隨機(jī)函數(shù)(例如HMAC-SHA512函數(shù)),把明文和一個(gè)鹽值作為輸入?yún)?shù),然后重復(fù)進(jìn)行運(yùn)算,并最終產(chǎn)生密鑰。如果重復(fù)的次數(shù)足夠大,破解的成本就會(huì)變得很高。而鹽值的添加也會(huì)增加“彩虹表”攻擊的難度。
DK的值由一個(gè)以上的block拼接而成。block的數(shù)量是dkLen/hLen的值。就是說如果PRF輸出的結(jié)果比期望得到的密鑰長(zhǎng)度要短,則要通過拼接多個(gè)結(jié)果以滿足密鑰的長(zhǎng)度:
DK = T1 || T2 || … || Tdklen/hlen
而每個(gè)block則通過則通過函數(shù)F得到:
Ti = F(Password, Salt, c, i)
在函數(shù)F里,PRF會(huì)進(jìn)行c次的運(yùn)算,然后把得到的結(jié)果進(jìn)行異或運(yùn)算,得到最終的值。
F(Password, Salt, c, i) = U1 ^ U2 ^ … ^ Uc
第一次,PRF會(huì)使用Password作為key,Salt作為鹽值進(jìn)行運(yùn)算。
U1 = PRF(Password, Salt)
而后續(xù)的c-1次則會(huì)使用上次得到的結(jié)果作為鹽值。
U2 = PRF(Password, U1)
…
Uc = PRF(Password, Uc-1)
這個(gè)最終生成的值就是種子。
從種子到母密鑰
種子通過不可逆 HMAC-SHA512 算法推算出 512 位的哈希串,左 256 位是主私鑰Master Private key(m), 右 256 位是主鏈碼 master chain code, 通過 m 結(jié)合推導(dǎo)公鑰的橢圓曲線算法能推導(dǎo)出與之對(duì)應(yīng)的 264 位主公鑰master public Key (M)。chain code 作為推導(dǎo)下級(jí)密鑰的熵。
子私鑰推導(dǎo)
使用 CKD(child key derivation) 函數(shù)從父密鑰(parent keys)推導(dǎo)子密鑰(child keys),CKD 由下列三個(gè)要素做單向散列哈希(one way hash function) 。
?父密鑰 (沒有壓縮過的橢圓曲線推導(dǎo)的私鑰或公鑰 ECDSA uncompressed key)
?鏈碼作為熵 (chain code 256 bits)
?子代索引序號(hào) (index 32 bits)
索引號(hào)個(gè)數(shù)為 2 的 32 次方,每個(gè)父級(jí)密鑰能推導(dǎo)出該數(shù)目一半的子密鑰。
索引號(hào)從 0x00 到 0x7FFFFFFF (0 to 2 的 21 次方減 1) 會(huì)生成正常的密鑰;索引號(hào)從 0x80000000 到 0xFFFFFFFF 會(huì)生成增強(qiáng)密鑰 )。
通過SHA512哈希生成的字符串,又進(jìn)一步拆分成左右兩個(gè)部分,左部分與父私鑰相加,成為子私鑰;右部分直接作為主鏈碼,用于生成下一級(jí)的子私鑰。
CKD 采用不可逆的 HMAC-SHA512 不可逆加密算法,子密鑰不能向上推導(dǎo)出父密鑰、同時(shí)也不能水平推導(dǎo)出同一級(jí)的密鑰。
擴(kuò)展密鑰
CKD 推導(dǎo)子密鑰的三個(gè)元素中,其中父密鑰和鏈碼結(jié)合統(tǒng)稱為擴(kuò)展密鑰 (Extended keys)。256 位的密鑰和 256 位的鏈碼串聯(lián)起來(lái)的 512 位就是擴(kuò)展密鑰。
1.包含私鑰的擴(kuò)展密鑰用以推導(dǎo)子私鑰,從子私鑰又可推導(dǎo)對(duì)應(yīng)的公鑰和比特幣地址
2.包含公鑰的擴(kuò)展密鑰用以推導(dǎo)子公鑰
擴(kuò)展密鑰使用 Base58Check 算法加上特定的前綴編碼,編碼得到的包含私鑰的前綴為 xprv, 包含公鑰的擴(kuò)展密鑰前綴為 xpub,相比比特幣的公私鑰,擴(kuò)展密鑰編碼之后得到的長(zhǎng)度為 512 或 513 位。
子公鑰推導(dǎo)
上述方法中通過推導(dǎo)出的私鑰可推導(dǎo)出對(duì)應(yīng)公鑰,但在隱藏私鑰的前提下同樣可以通過公鑰推導(dǎo)出子公鑰,極大加強(qiáng)安全性。在只需要生成地址接受比特幣而無(wú)權(quán)消費(fèi)的場(chǎng)景下非常有用,通過公鑰擴(kuò)展密鑰能生成無(wú)窮盡的公鑰和比特幣地址。
子私鑰推導(dǎo)流程和子公鑰流程基本一樣,差異之處有兩點(diǎn):
1.把子私鑰推導(dǎo)過程中私鑰替換為公鑰。
2.子公鑰推導(dǎo)出對(duì)應(yīng)出與之的子鏈碼
增強(qiáng)擴(kuò)展密鑰推導(dǎo)
密鑰需加強(qiáng)保管以免泄漏,泄漏私鑰意味著對(duì)應(yīng)的地址上的幣可被轉(zhuǎn)走、泄漏公鑰意味著錢包的隱私被泄漏。增強(qiáng)密鑰推導(dǎo) (Hardened child key derivation) 解決下述兩個(gè)問題:
1.雖然泄漏公鑰并不會(huì)導(dǎo)致丟幣,但含有公鑰的擴(kuò)展密鑰泄漏會(huì)導(dǎo)致以此為根節(jié)點(diǎn)推導(dǎo)出來(lái)的擴(kuò)展公鑰全部泄漏,一定程度上破壞了隱私性。
2.泄漏擴(kuò)展公鑰加上該公鑰推導(dǎo)出的后任一代擴(kuò)展公鑰對(duì)應(yīng)的私鑰有被推導(dǎo)出該擴(kuò)展公鑰的所有后代私鑰的可能性。
于此,BIP32 協(xié)議把 CKD 函數(shù)改為 HKD (hardened key derivation formula) 生成增強(qiáng)密鑰推導(dǎo)函數(shù)。
CKD 函數(shù)以推導(dǎo)擴(kuò)展密鑰的序列號(hào) ( 0x00 到 0x7FFFFFFF)、父鏈碼和父公鑰生或父私鑰成子鏈碼和子公鑰,子私鑰從父私鑰推導(dǎo);而 HKD 通過父私鑰、父鏈碼和推導(dǎo)增強(qiáng)擴(kuò)展密鑰的序列號(hào) (0x80000000 到 0xFFFFFFFF) 增強(qiáng)子私鑰和增強(qiáng)子鏈碼。
總結(jié)
以上是生活随笔為你收集整理的钱包原理——助记词与公私钥的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于java财务管理系统(java毕业设
- 下一篇: 工业安全大数据汇聚与治理、2、多模态数据