Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

9.6. 太坊賬戶管理 keystore 檔案



Post author: Martin Wang
Post link: http://stevenocean.github.io/2018/04/02/about-ethereum-keystore.html
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.

9.6.1. 什麼是 keystore 檔案

以太坊的每個外部賬戶都是由一對密鑰(一個公鑰和一個私鑰)定義的。賬戶以地址為索引,地址由公鑰衍生而來,取公鑰的最後 20個位元組。每對私鑰 /地址都編碼在一個鑰匙檔案裡,也就是我們說的keystore檔案。該檔案是 JSON 文本檔案,可以用任何文本編輯器打開和瀏覽。鑰匙檔案的關鍵部分,賬戶私鑰,通常用你創建帳戶時設置的密碼進行加密。也就是說 keystore 檔案,就是你獨有的、用於簽署交易的以太坊私鑰的加密檔案。如果你丟失了這個檔案,你就丟失了私鑰,意味着你失去了簽署交易的能力,意味着你的資金被永久的鎖定在了你的賬戶裡。

9.6.2. keystore 檔案的內容

我們先看一下keystore檔案都包含哪些數據:

			
neo@MacBook-Pro ~/Library/Ethereum/testnet/keystore % cat UTC--2018-04-01T09-30-44.943874000Z--d5eeae04932dbc2e65b948a76a6cdfd44323a5dd
{	"address":"d5eeae04932dbc2e65b948a76a6cdfd44323a5dd",
	"crypto":{
		"cipher":"aes-128-ctr",
		"ciphertext":"16715298517abb35cb44e9a32d1f81f21ead63006c57eb0ff434318a6ea3ed3f",
		"cipherparams":{
			"iv":"1ff6fea34e682158e7660ae67960ff76"
		},
		"kdf":"scrypt",
		"kdfparams":{
			"dklen":32,
			"n":262144,
			"p":1,
			"r":8,
			"salt":"a99af42dac2363db631ef7c57a25705c7efdee73b19c11b27f9a91d41cd32d1c"
		},
		"mac":"dcd248fb996604dfcb69a86604af3992b4a9b8d20cc05e0c7608189dbbe66eda"
	},
	"id":"55edb869-1c86-4c68-924e-8247575a158b",
	"version":3
}			
			
			



我們可以看到大部分內容都在 crypto 欄位中,這裡包括:

cipher:對稱 AES 算法的名稱;
cipherparams:上述 cipher 算法需要的參數;
ciphertext:你的以太坊私鑰使用上述 cipher 算法進行加密;
kdf:密鑰生成函數,用於讓你用密碼加密 keystore 檔案;
kdfparams:上述 kdf 算法需要的參數;
Mac:用於驗證密碼的代碼。

9.6.3. keystore檔案如何工作的?

9.6.3.1. 加密你的私鑰

就像之前提到的,一個以太坊賬戶就是用於加密簽署交易的一個私鑰-公鑰對。為了確保你的私鑰沒有在檔案中明文存儲(即任何人只要能得到這個檔案就能讀),使用強對稱算法(cipher)對其加密至關重要。

這些對稱算法使用密鑰來加密數據。加密後的數據可以使用相同的方法和同樣的密鑰來解密,因此算法命名為對稱算法。在本文中,我們稱這個對稱密鑰為解密密鑰,因為它將用於對我們的以太坊私鑰進行解密。

加密過程,如下圖:

以下是 cipher,cipherparams 和 ciphertext 對應的概念:

  1. cipher: 是用於加密以太坊私鑰的對稱加密算法。此處cipher用的是 aes-128-ctr 加密模式。

  2. cipherparams: 是 aes-128-ctr 加密算法需要的參數。在這裡,用到的唯一的參數 iv,是aes-128-ctr加密算法需要的初始化向量。

  3. ciphertext: 密文是 aes-128-ctr 函數的加密輸入。

在這裡,你已經有了進行解密以太坊私鑰計算所需要的一切。但是我們首先要取回解密密鑰。

9.6.3.2. 用你的密碼來保護它

要確保解鎖你的賬戶很容易,你不需要記住你的每一個又長又非用戶友好型的用於解密 ciphertext 密文解密密鑰。相反,以太坊開發者選擇了基于密碼的保護,也就是說你只需要輸入密碼就能拿回解密密鑰。

為了能做到這一點,以太坊用了一個密鑰生成函數,輸入密碼和一系列參數就能計算解密密鑰。

這就是 kdf 和 kdfparams 的用途:

  1. kdf: 是一個密鑰生成函數,根據你的密碼計算(或者取回)解密密鑰。在這裡,kdf 用的是scrypt算法。

  2. kdfparams: 是scrypt函數需要的參數。在這裡,簡單來說,dklen、n、r、p 和 salt 是 kdf 函數的參數。

在這裡,用 kdfparams 參數對 scrypt 函數進行調整,反饋到我們的密碼中,你就會得到解密密鑰也就是密鑰生成函數的輸出。

9.6.3.3. 確認輸入的密碼是正確的

這就是 keystore 檔案中 mac 值起作用的地方。在密鑰生成函數執行之後,它的輸出(解密密鑰)和 ciphertext 密文就被處理,並且和 mac(就像一種認可的印章)作比較。如果結果和 mac 相同,那麼密碼就是正確的,並且解密就可以開始了。

9.6.3.4. 將這三步結合起來

首先,你輸入了密碼,這個密碼作為 kdf 密鑰生成函數的輸入,來計算解密密鑰。然後,剛剛計算出的解密密鑰和 ciphertext 密文連接併進行處理,和 mac 比較來確保密碼是正確的。最後,通過 cipher 對稱函數用解密密鑰對 ciphertext 密文解密。

就像你從圖中可以看到的,整個過程可以看做一個黑盒(不過,圖中是個灰盒),你的密碼是惟一的輸入,你的以太坊私鑰是惟一的輸出。所需的其他信息都可以在你的以太坊賬戶創建時生成的keystore檔案中獲得。