進入keystore管理以太坊私鑰的障礙很大,主要是由於以太坊客戶端在直接的命令行或圖形界面下隱藏了大部分的密碼複雜性。html
例如,用geth:git
$ geth account new Your new account is locked with a password. Please give a password. Do not forget this password. Passphrase: Repeat passphrase: Address: {008aeeda4d805471df9b2a5b0f38a0c3bcba786b} $ geth account list Account #0: {8a1c4d573cc29a96547816522cfe0b266e88abac} keystore:~/.ethereum/keystore/UTC--<created_date_time>-- 008aeeda4d805471df9b2a5b0f38a0c3bcba786b
我只須要輸入3個單詞就能建立一個新帳戶。而後輸入兩遍密碼,就這麼簡單!個人以太坊keystore文件就建立了。github
你須要把那些很是珍貴的keystore文件備份、存儲在一個或多個隱祕的位置,這樣就只有你能獲取這些文件並取到資金。算法
從經驗來看,當我沒有徹底理解一個新概念的微妙之處,而且過度依賴抽象層和現有工具來讓個人生活更輕鬆時,我頗有可能忘記一些事情,採起沒必要要的捷徑而且搞砸它。搞砸的時候,可能就是會以我辛苦掙來的以太幣被永久鎖定而了結(幸虧它尚未發生!)。安全
幸運的是,做爲一個以太坊用戶,你能搞砸的方式並很少:函數
在本文中,咱們將爲你介紹以太坊私鑰是如何從 keystore 文件中算出來的。咱們將討論加密函數(對稱加密,密鑰生成函數,SHA3 哈希算法),但咱們會盡量的保證簡明直接地來解釋上述問題。工具
以太坊的 keystore 文件(Linux 系統存儲在 ~/.ethereum/keystore 或者 Windows 系統存儲在 C:\Users<User>\Appdata/Roaming/Ethereum/keystore)是你獨有的、用於簽署交易的以太坊私鑰的加密文件。若是你丟失了這個文件,你就丟失了私鑰,意味着你失去了簽署交易的能力,意味着你的資金被永久的鎖定在了你的帳戶裏。this
固然,你能夠直接把你的以太坊私鑰存儲在一個加密文件裏,可是這樣你的私鑰容易受到攻擊,攻擊者簡單的讀取你的文件、用你的私鑰簽署交易,把錢轉到他們的帳戶中。你的幣會在你意識到發生什麼了以前的短期內丟失。加密
這就是以太坊 keystore 文件被建立的緣由:它容許你以加密的方式存儲密鑰。這是安全性(一個攻擊者須要 keystore 文件和你的密碼才能盜取你的資金)和可用性(你只須要keystore文件和密碼就能用你的錢了)二者之間完美的權衡。命令行
爲了讓你發送一些以太幣,大多數的以太坊客戶端會讓你輸入密碼(與建立帳戶時密碼相同)以解密你的以太坊私鑰。一旦解密,客戶端程序就獲得私鑰簽署交易,容許你移動資金。
若是你打開一個你的帳戶文件,它看起來像這樣(取自這裏):
ount’s file, it would look like this (taken from here):
$ cat ~/.ethereum/keystore/UTC--<created_date_time>-- 008aeeda4d805471df9b2a5b0f38a0c3bcba786b { "crypto" : { "cipher" : "aes-128-ctr", "cipherparams" : { "iv" : "83dbcc02d8ccb40e466191a123791e0e" }, "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", "kdf" : "scrypt", "kdfparams" : { "dklen" : 32, "n" : 262144, "r" : 1, "p" : 8, "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" }, "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" }, "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", "version" : 3 }
一個有許多神奇的參數的粗笨的 JSON 文件,彷佛與複雜的加密操做相關。這毫不吸引人。
若是你看這個 keystore 文件的結構,你會看到大部份內容都是在「crypto」中的:
"crypto" : { "cipher" : "aes-128-ctr", "cipherparams" : { "iv" : "83dbcc02d8ccb40e466191a123791e0e" }, "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", "kdf" : "scrypt", "kdfparams" : { "dklen" : 32, "n" : 262144, "r" : 1, "p" : 8, "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" }, "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" },
這包括:
讓咱們看看他們是如何協同工做的,如何在你的密碼下保護 keystore 文件。
就像以前提到的,一個以太坊帳戶就是用於加密簽署交易的一個私鑰 —公鑰對。爲了確保你的私鑰沒有在文件中明文存儲(即任何人只要能獲得這個文件就能讀),使用強對稱算法(cipher)對其加密相當重要。
這些對稱算法使用密鑰來加密數據。加密後的數據可使用相同的方法和一樣的密鑰來解密,所以算法命名爲對稱算法。在本文中,咱們稱這個對稱密鑰爲解密密鑰,由於它將用於對咱們的以太坊私鑰進行解密。
如下是 cipher,cipherparams 和 ciphertext 對應的概念:
因此,在這裏,你已經有了進行解密以太坊私鑰計算所須要的一切...等等。你須要首先取回你的解密密鑰。
-ciphertex 密文的對稱解密-
要確保解鎖你的帳戶很容易,你不須要記住你的每個又長又非用戶友好型的用於解密 ciphertext 密文解密密鑰。相反,以太坊開發者選擇了基於密碼的保護,也就是說你只須要輸入密碼就能拿回解密密鑰。
爲了能作到這一點,以太坊用了一個密鑰生成函數,輸入密碼和一系列參數就能計算解密密鑰。
這就是 kdf 和 kdfparams 的用途:
在這裏,用 kdfparams 參數對 scrypt 函數進行調整,反饋到咱們的密碼中,你就會獲得解密密鑰也就是密鑰生成函數的輸出。
-用密碼生成密鑰-
咱們描述了用密碼和 keystore 文件生成以太坊私鑰所須要的全部東西。然而,若是解鎖帳戶的密碼錯誤會發生什麼?
根據迄今爲止咱們所看到的,全部操做(密碼派生和解密)都會成功,可是最終計算的以太坊私鑰不是正確的,這首先違背了密鑰文件的使用初衷!
咱們要保證輸入解鎖帳戶的密碼是正確的,和最初建立 keystore 文件時同樣(回想一下 geth 下建立新帳戶時兩次輸入的密碼)。
這就是 keystore 文件中 mac 值起做用的地方。在密鑰生成函數執行以後,它的輸出(解密密鑰)和 ciphertext 密文就被處理【注1】,而且和 mac(就像一種承認的印章)做比較。若是結果和 mac 相同,那麼密碼就是正確的,而且解密就能夠開始了。
【注1】這裏有點簡略了。在和 mac 進行比較以前,解密密鑰(左起第二字節開始的16字節)要和 ciphertext 密文鏈接在一塊兒,並進行哈希散列(用SHA3-256的方法)。 更多信息請訪問這裏。
唷! 若是你已經作到了這一點,那麼恭喜你! 🎉🎊
讓咱們回顧一下咱們描述的3個函數。
首先,你輸入了密碼,這個密碼做爲 kdf 密鑰生成函數的輸入,來計算解密密鑰。而後,剛剛計算出的解密密鑰和 ciphertext 密文鏈接並進行處理,和 mac 比較來確保密碼是正確的。最後,經過 cipher 對稱函數用解密密鑰對 ciphertext 密文解密。
瞧!解密的結果是你的以太坊私鑰。 你能夠在這裏看看整個過程:
就像你從圖中能夠看到的,整個過程能夠看作一個黑盒(不過,圖中是個灰盒),你的密碼是唯一的輸入,你的以太坊私鑰是唯一的輸出。所需的其餘信息均可以在你的以太坊帳戶建立時生成的keystore文件中得到。
因爲這個緣由,請確保你的密碼足夠強(而且不管如何你要記住它!)才能保證即便攻擊者偷到了你的keystore文件也不能輕易獲得你的私鑰。