數字簽名作為去中心化的身份鑑別方案在區塊鏈世界裡大獲成功,廣為使用的基於橢圓曲線的數字簽名方案,尤以基於Secp256k1、Ed25519等曲線為基礎算術運算的簽名演算法最為常見。但是無論是哪種方案的使用,正確的私鑰才是操作地址或賬戶的唯一方法。這也是“私鑰即資產”這一概念被區塊鏈使用者信奉的原因之一。
私鑰是密碼學或者說是數學概念,在不同的空間的展現形式各不相同,例如人類可讀的世界裡,常被編碼成“助記詞”的形式,並且這種做法已經被區塊鏈社羣所標準化,形成了諸如BIP39的標準助記詞列表。在數字世界中,私鑰的儲存形式也可以將助記詞自己數字化儲存。但是由於在數字世界中,容易被木馬或者駭客窺探到,所以不能明碼的儲存助記詞(因為編碼規則公開,這樣等同於明文儲存私鑰),通常採用keystore的方式來儲存私鑰。
DEAX原生錢包Keystore儲存方案
Keystore是一種介於去中心化身份鑑別方案與中心化身份鑑別方案之間的一種方案。由於不是中心化的,所有可以防止伺服器濫用使用者權力的問題,但是同時它只能是離線的,所以可能會遭受到離線暴力攻擊。
通常來說,一個功能完整的Keystore儲存方案必須要包含如下幾個模組或演算法:
• 隨機數發生器模組;
• 基於口令(或者基於其他身份資訊的)的金鑰生成演算法;
• 認證加密方案;
1. 隨機數生成演算法
Keystore是私鑰儲存的一種解決方案,需要一種產生私鑰的方法。通常為了私鑰之間不產生衝突以及不被暴力破解,私鑰的產生都採取隨機產生方式,這也是封閉系統產生金鑰(私鑰、對稱金鑰)的主要方式。
軟體系統不能產生真的隨機數,需要依賴於更底層的作業系統或者API中的隨機數發生器。DAEX錢包Keystore系統基於Go語言的隨機數發生器介面,關於該介面的相關資訊,可參考此處。
2. 基於口令的金鑰生成演算法
Keystore檔案通常運用對稱加密方案來儲存私鑰(或者私鑰列表),對稱加密方案需要對稱金鑰(即使某些Keystore方案運用非對稱加密方案,但是也需要公鑰加密以及私鑰來解密),此對稱金鑰需要使用者容易記憶(如若不然,回到了原來的私鑰儲存和記憶的問題)。最常見的易於記憶的方式即使用者口令。但是使用者口令空間相對來說小很多,並不是一種產生直接的對稱金鑰的方式。通常的解決方法是利用基於口令的金鑰生成演算法,來產生對稱金鑰。
DAEX錢包的基於口令的對稱金鑰生成演算法採用了RFC 5869標準中的HKDF演算法(HMAC-based Extract-and-Expand Key Derivation Function)。此標準廣泛的應用於例如IKEv2,PANA,EAP-AKA等協議中,是一種基於HMAC的金鑰生成演算法。該演算法需要產生64byte(512bit)的隨機數作為鹽值(salt)共同參與對稱金鑰匯出運算。鹽值記錄到最終的Keystore檔案中,一邊恢復該對稱金鑰時使用。
如果用其他的身份資訊來代替口令,如指紋、面部等身份資訊等,可以得到基於其他身份資訊的金鑰生成演算法。前提是需要有此類專業的裝置。例如具有采集指紋資訊的硬體錢包,可以採用基於指紋的方案。
3. 認證加密方案
如上所說,Keystore檔案將加密儲存使用者的私鑰,但是僅僅加密儲存私鑰並不夠。例如使用者輸入錯誤的口令,可能會恢復出一個私鑰,但是這個私鑰已經不是真正的擁有資產的那個私鑰了,錢包並不知道恢復的私鑰是否正確。這是因為錯誤的口令在恢復私鑰的過程中,由於解密演算法並沒有識別出口令的正確性而導致的(這是因為僅有的加密功能是不具備識別功能的)。
因此,Keystore需要鑑別功能,用於甄別輸入口令的正確性。將鑑別與加密一同合成一個模組,用認證加密方案來解決。
DAEX錢包運用AES-256-GCM方案來實現金鑰的認證加密儲存。AES-256-GCM使用AES作為基礎的加密模組,金鑰長度與分組長度均為256bit,對於不足或者超出256bit的明文,採用標準的填充方式,填充值256bit的整數倍。用AES-256演算法對一系列的遞增的計數器(或稱為nonce)的值進行運算,並將運算結果與明文分組進行異或運算得到一系列的加密輸出結果。AES-256-GCM的鑑別部分採用基於伽羅華域乘法(一種特殊的乘法)。將以上得出的一系列加密輸出的,依次進行伽羅華域乘法,最終得到用於鑑別的資料。
寫在最後
正如前面所述,現在絕大多數區塊鏈專案的原生錢包都使用Keystore檔案來加密儲存使用者的私鑰資料,使用者“口令+Keystore“才能真正拿到私鑰。深層次剖析是,Keystore檔案並且僅有Keystore檔案儲存了使用者私鑰資料,而且是加密儲存,使用者口令只是開啟Keystore的“鑰匙”。理論上使用者口令與真正私鑰是沒有任何關係的。但是遺憾的是,筆者在做開發前的調研時發現,在部分專案中,存在用使用者口令直接產生最終私鑰的方法,或是存在於專案原始碼中,或是存在於專案的SDK中、或是存在於部分應用中。運用這個漏洞,筆者真的搜尋到了一些地址,成功爆破其私鑰。這是專案體系中一個極大的漏洞。因為口令相對於私鑰的空間小很多,很容易透過暴力破解口令來破解。
DAEX在專案本身原始碼層面,不提供透過口令產生私鑰的介面,杜絕使用口令直接產生私鑰,並且不足夠的熵將無法產生私鑰。同時DAEX將提示第三方開發者,堅決不能採用口令直接產生私鑰的方法。從而保護終端使用者資產的安全。