1. 程式人生 > >助記詞

助記詞

現在區塊鏈市場上的大部分錢包,都是通過助記詞來備份錢包的。當然也有不少的錢包是通過私鑰來備份錢包的。不管是通過助記詞備份錢包,還是痛私鑰備份錢包,其實在原理上都是大同小異。一般的錢包都是通過助記詞生成隨機數種子,然後再通過隨機數種子生成根私鑰,再通過BIP分層協議生成各個幣種賬戶的私鑰。因而助記詞是一個錢包的起始段,也是一個錢包的重要技術組成部分。本章咱們將詳細地講解助記詞相關的知識。

一.助記詞原理

助記詞並不是一個新概念,早在很多行業,就出現了助記詞的概念。發音為“ne-manik”的最純粹形式的助記符是一種字母,單詞或關聯模式,可讓您輕鬆記住資訊,並已被人類使用了數千年。換句話說,它可以是一個非常有用的工具,幫助我們記住我們需要記住的重要資訊。

在比特幣中,助記符采用相同的基本原則,即使用一組單詞生成一個獨特的錢包短語,為您提供一個人類可讀的單詞格式,以備份您的錢包進行恢復。用於生成這些短語的助記符程式碼在2013年通過比特幣改進提案或BIP引入比特幣。BIP描述了助記符程式碼或助記句的實現,一組容易記憶的單詞,用於生成確定性錢包。它由兩部分組成:生成助記符,並將其轉換為二進位制種子。 該種子可以稍後用於使用BIP-0032或類似方法生成確定性錢包。

一般來說私鑰都有256位,以64個字母數字構成的16進位制字串表示。備份私鑰的時候直接抄錄64個字元顯然是很容易產生錯誤的,而且易讀性也很差,使用者體驗度顯然就會降低,而助記詞的出現剛好解決了這個尷尬的局面,助記詞是明文私鑰的另一種表現形式。助記詞出現的目的是為了幫助使用者記憶複雜的私鑰 (64位的雜湊值)。助記詞一般由12、15、18、21個單詞構成, 這些單詞都取自一個固定詞庫, 其生成順序也是按照一定演算法而來, 所以使用者沒必要擔心隨便輸入12個單詞就會生成一個地址。雖然助記詞和 Keystore 都可以作為私鑰的另一種表現形式, 但與 Keystore 不同的是, 助記詞是未經加密的私鑰, 沒有任何安全性可言, 任何人得到了你的助記詞, 可以不費吹灰之力的奪走你的資產。

目前錢包分為兩種:非確定性錢包和確定性錢包,非確定錢包就是隨機生成多個私鑰,錢包管理這些私鑰。這種錢包私鑰不易於管理。但如果設計錢包的人水平過高的話,也可以設計得很好。確定性錢包是通過種子來生成不同賬戶的私鑰,我們只要記住助記詞就行,用助記詞生成種子,再去生成錢包相關的地址和私鑰。

下面我們看看種子生成的流程

.:
.:

1.從熵到助記詞

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

如下圖

.:
.:

2.從助記詞生成種子

助記詞表示長度為128至256位的熵。 通過使用金鑰延伸函式PBKDF2,熵被用於匯出較長的(512位)種子。
PBKDF2的基本原理是通過一個偽隨機函式(例如HMAC函式),把明文和一個鹽值作為輸入引數,然後重複進行運算,並最終產生金鑰。如果重複的次數足夠大,破解的成本就會變得很高。而鹽值的新增也會增加“彩虹表”攻擊的難度。
比特幣錢包中,PBKDF2函式的第一個引數是助記詞,第二個引數鹽,由字串常數“助記詞”與可選的使用者提供的密碼字串連線組成。使用HMAC-SHA512演算法,使用2048次雜湊來延伸助記符和鹽引數,產生一個512位的值作為其最終輸出。 這個512位的值就是種子。如圖

.:
.:

3.從種子到母金鑰

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

.:
.:

4.從母金鑰到子金鑰

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

.:
.:

5.擴充套件金鑰

母金鑰和鏈碼結合叫做擴充套件金鑰,擁有擴充套件私鑰可以推匯出子私鑰,擴充套件公鑰可以推匯出子公鑰。擁有擴充套件公鑰就可以推匯出子公鑰,在伺服器不需要母私鑰也可以,這樣就更安全更方便。但是還有一個問題,那就是擴充套件公鑰包含有鏈碼,如果子私鑰被知道或者被洩漏的話,鏈碼就可以被用來衍生所有的其他子私鑰。簡單地洩露的私鑰以及一個母鏈碼,可以暴露所有的子金鑰。更糟糕的是,子私鑰與母鏈碼可以用來推斷母私鑰。
為此,HD錢包使用一種叫做硬化衍生(hardened derivation)的替代衍生函式。這就“打破”了母公鑰以及子鏈碼之間的關係。這個硬化衍生函式使用了母私鑰去推導子鏈碼,而不是母公鑰。這就在母/子順序中創造了一道“防火牆”——有鏈碼但並不能夠用來推運算元鏈碼或者姊妹私鑰。強化衍生函式看起來幾乎與一般的衍生的子私鑰相同,不同的是母私鑰被用來輸入雜湊函式中而不是母公鑰。如圖

.:
.:

二.生成助記詞

1.生成12個助記詞

var bip39 = require('bip39')
var mnemonic = bip39.generateMnemonic()
console.log(mnemonic);

var bip39 = require('bip39')
var mnemonic = bip39.generateMnemonic(128)
console.log(mnemonic);	

2.生成15個助記詞

var bip39 = require('bip39')
var mnemonic = bip39.generateMnemonic(160)
console.log(mnemonic);	

3.生成18個助記詞

var bip39 = require('bip39')
var mnemonic = bip39.generateMnemonic(192)
console.log(mnemonic);	

4.生成21個助記詞

var bip39 = require('bip39')
var mnemonic = bip39.generateMnemonic(224)
console.log(mnemonic);	

5.生成24個助記詞

var bip39 = require('bip39')
var mnemonic = bip39.generateMnemonic(256)
console.log(mnemonic);	

6.生成中文助記詞

var mnemonicS = bip39.generateMnemonic(128, null, bip39.wordlists.chinese_simplified);
console.log(mnemonicS);

以上根據傳值的的大小限定助記詞的個數

目前助記詞庫能夠生成“簡體中文”,“繁體中文”,“英文”,“法文”,“義大利文”,“日文”,“韓文”和西班牙文。

三.助記詞編解碼

1.編碼助記詞

var bip39 = require('bip39')
var mnemonic = bip39.generateMnemonic()
var encrytMnemonic = bip39.mnemonicToEntropy(mnemonic)
console.log(encrytMnemonic);

2.解碼助記詞

var bip39 = require('bip39')
var mnemonic = bip39.generateMnemonic()
console.log(mnemonic);
var encrytMnemonic = bip39.mnemonicToEntropy(mnemonic)
var word = bip39.entropyToMnemonic(encrytMnemonic)
console.log(word);

四.生成隨機數種子

var mnemonicE = bip39.generateMnemonic()
console.log(mnemonicE);
var Seed= bip39.mnemonicToSeed(mnemonicE)
var seedHex= bip39.mnemonicToSeedHex(mnemonicE)
console.log(Seed);
console.log(seedHex);

五.驗證助記詞

var mnemonic = bip39.generateMnemonic()
console.log(mnemonic);
var bool = bip39.validateMnemonic(mnemonic)

六.助記詞開源庫

https://github.com/bitcoinjs/bip39

區塊鏈錢包技術指南一書GitHub地址:https://github.com/guoshijiang/blockchain-wallet/