MOAC區塊鏈助記詞

 

1.什麼是助記詞

 

擁有數字貨幣資產的人都知道,私鑰的備份是非常重要的,有私鑰就擁有該私鑰對應賬戶上的所有資產。一般來說私鑰都有 256 位,以 64 個字母數字構成的 16 進制字符串表示。直接抄錄這 64 個字母數字是很容易搞錯的。

 

助記詞是明文私鑰的另一種表現形式, 最早是由BIP39提案提出, 其目的是爲了幫助用戶記憶複雜的私鑰 (64位的哈希值)。助記詞一般由12、15、18、21、24個單詞構成, 這些單詞都取自一個固定詞庫, 其生成順序也是按照一定算法而來, 所以用戶沒必要擔心隨便輸入 12 個單詞就會生成一個地址。

 

雖然助記詞和 Keystore 都可以作爲私鑰的另一種表現形式, 但與 Keystore 不同的是, 助記詞是未經加密的私鑰, 沒有任何安全性可言, 任何人得到了你的助記詞, 可以不費吹灰之力的奪走你的資產。

 

2.BIP

 

要弄清楚助記詞與私鑰的關係,得清楚BIP協議,是Bitcoin Improvement Proposals的縮寫,意思是Bitcoin 的改進建議,用於提出 Bitcoin 的新功能或改進措施。BIP協議衍生了很多的版本,主要有BIP32、BIP39、BIP44。

 

BIP32

 

BIP32是 HD錢包的核心提案,通過種子來生成主私鑰,然後派生海量的子私鑰和地址,種子是一串很長的隨機數。

 

BIP39

 

由於種子是一串很長的隨機數,不利於記錄,所以我們用算法將種子轉化爲一串12 ~ 24個的單詞,方便保存記錄,這就是BIP39,它擴展了 HD錢包種子的生成算法。

 

BIP44

 

BIP44 是在 BIP32 和 BIP43 的基礎上增加多幣種,提出的層次結構非常全面,它允許處理多個幣種,多個帳戶,每個帳戶有數百萬個地址。

 

在BIP32路徑中定義以下5個級別:

m/purpse'/coin_type'/account'/change/address_index

 

purpose:在BIP43之後建議將常數設置爲44'。表示根據BIP44規範使用該節點的子樹。

 

Coin_type:幣種,代表一個主節點(種子)可用於無限數量的獨立加密幣,如比特幣,Litecoin或Namecoin。此級別爲每個加密幣創建一個單獨的子樹,避免重用已經在其它鏈上存在的地址。開發人員可以爲他們的項目註冊未使用的號碼。

 

Account:賬戶,此級別爲了設置獨立的用戶身份可以將所有幣种放在一個的帳戶中,從0開始按順序遞增。

 

Change:常量0用於外部鏈,常量1用於內部鏈,外部鏈用於錢包在外部用於接收和付款。內部鏈用於在錢包外部不可見的地址,如返回交易變更。

 

Address_index:地址索引,按順序遞增的方式從索引0開始編號。

 

BIP44的規則使得 HD錢包非常強大,用戶只需要保存一個種子,就能控制所有幣種,所有賬戶的錢包,因此由BIP39 生成的助記詞非常重要,所以一定安全妥善保管,那麼會不會被破解呢?如果一個 HD 錢包助記詞是 12 個單詞,一共有 2048 個單詞可能性,那麼隨機的生成的助記詞所有可能性大概是5e+39,因此幾乎不可能被破解。

 

HD錢包

 

通過BIP協議生成賬號的錢包叫做HD錢包。這個HD錢包,並不是Hardware Wallet硬件錢包,這裏的 HD 是Hierarchical Deterministic的縮寫,意思是分層確定性錢包 。

 

以太坊對BIP的支持

BIP是用於提出 Bitcoin 的新功能或改進措施,那麼對於以太坊來說如何支持呢?

以太坊在EIPs/issues/85中討論的結果,也採用了 BIP32 的做法,提議 HD 路徑爲 :m/44'/60'/0'/0/n,n 是第 n 次生成地址。

 

3.助記詞到私鑰的步驟

 

3.1 從熵到助記詞

隨機生成一個128到258位的數字,叫做熵; 熵通過SHA256哈希得一個值,取前面的幾位(熵長/32),記爲y; 熵和y組成一個新的序列,將新序列以11位爲一部分,已經預先定義2048個單詞的字典做對應; 生成的有順序的單詞組就是助記詞。

 

3.2 從助記詞生成種子

助記詞表示長度爲128至256位的熵。 通過使用密鑰延伸函數PBKDF2,熵被用於導出較長的(512位)種子。

 

PBKDF2的基本原理是通過一個僞隨機函數(例如HMAC函數),把明文和一個鹽值作爲輸入參數,然後重複進行運算,並最終產生密鑰。如果重複的次數足夠大,破解的成本就會變得很高。而鹽值的添加也會增加「彩虹表」攻擊的難度。

 

比特幣錢包中,PBKDF2函數的第一個參數是助記詞,第二個參數鹽,由字符串常數「助記詞」與可選的用戶提供的密碼字符串連接組成。使用HMAC-SHA512算法,使用2048次哈希來延伸助記符和鹽參數,產生一個512位的值作爲其最終輸出。 這個512位的值就是種子。

 

3.3 從種子到母密鑰

512位分成平均分成兩部分,左邊的256位爲母私鑰,右邊的256位爲鏈碼。母私鑰、鏈碼和索引號,CKD(child key derivation)函數去從母密鑰衍生出子密鑰。

 

3.4 從母密鑰到子密鑰

母密鑰、鏈碼、索引合併在一起並且用HMAC-SHA512函數散列之後可以產生512位的散列。所得的散列可被拆分爲兩部分。散列右半部分的256位產出可以給子鏈當鏈碼。左半部分256位散列以及索引碼被加載在母私鑰上來衍生子私鑰。在圖中,我們看到這個說明——索引集被設爲0去生產母密鑰的第0個子密鑰(第一個通過索 引)。

 

3.5 擴展密鑰

母密鑰和鏈碼結合叫做擴展密鑰,擁有擴展私鑰可以推導出子私鑰,擴展公鑰可以推導出子公鑰。擁有擴展公鑰就可以推導出子公鑰,在服務器不需要母私鑰也可以,這樣就更安全更方便。但是還有一個問題,那就是擴展公鑰包含有鏈碼,如果子私鑰被知道或者被泄漏的話,鏈碼就可以被用來衍生所有的其他子私鑰。簡單地泄露的私鑰以及一個母鏈碼,可以暴露所有的子密鑰。更糟糕的是,子私鑰與母鏈碼可以用來推斷母私鑰。

基本流程見下圖:

 

 

4.生成助記詞

生成不同個數的助記詞代碼:

 

運行結果:

 

5.助記詞編解碼

5.1 編碼

運行結果:

 

5.2 解碼

 

運行結果:

 

5.3 驗證助記詞

運行結果:

 

6.生成隨機數種子

 

運行結果:

 

這裏是個異步過程,因此代碼修改爲:

運行結果:

 

7.生成私鑰

 

運行結果: