如果你常在區塊鏈的世界衝浪,肯定會有一個抱團取暖的社團分享訊息,每當夥伴分享區塊鏈社會事件,如暴力討債、礦場偷電、名人錢包被盜事件⋯⋯往往是見怪不鮮不能引起你的共鳴,但看到夥伴們錢包被盜的事情,肯定會令大家豎直椅背開始團購冷錢包,或是把電腦、手機的助記詞刪除改用紙質筆記本。
隊友聽我分享完點頭如搗蒜,隨即把所有數位的痕跡都抹除,並將錢包的助記詞抄送在紙質筆記本上,然而隊友不諳區塊鏈的基礎知識,只抄送了11位助記詞!找尋那遺失的1位的過程正是本文要分享的。
硬幹程式之前,必須先確認規格,才能衡量這個硬幹的可能性,Tezos如其他熱門的加密貨幣,如:Ether、Bitcoin一樣,使用BIP39的規格設計助記詞,這裡有一些重點幫大家濃縮:
助記詞其實就是由2048個不同的單字組成,每一個單字對應一個二進制號碼,從
0x00000000000到0x11111111111,對整個表格有興趣請移駕這裡。首四位不會重複,如:642號expand與643號expect只有三位重複,為的是避免助記詞在抄送的過程中出現筆誤的現象。
支援多種語言,如:英文、日文、韓文、西班牙文、簡體中文、繁體中文、法文、義大利文、捷克文、葡萄牙文都可以有助記詞,但目前大多數錢包都是使用英文助記詞。
透過以上的推理,只需要從表格中取1個助記詞跟11位已知的助記詞進行排列組合後生成『錢包地址』,再拿這個『錢包地址』跟自己的『錢包地址』進行比對就能知道答案了,於是我就寫了一段Python程式:
from pytezos.crypto.key import Key
from mnemonic import Mnemonic
import numpy as np
incomplete_words = [...]
target_address = "tz1..."
size = len(Mnemonic(LANGUAGE).wordlist)
for position in range(12):
print("======")
print(position)
for index in range(size):
# pick one from world list vector
variable = Mnemonic(LANGUAGE).wordlist[index]
# insert above to an incomplete seed phrase array
input_data = np.insert(incomplete_words, position, variable)
# as string format
input_data_str = ' '.join(input_data)
try:
sk = Key.from_mnemonic(mnemonic=input_data_str)
if(sk.public_key_hash() == target_address):
print(position, index, input_data)
except Exception as e:
pass
但以上方法但始終找不到正確的地址。
後來翻了一下BIP44的規格,發現常用的瀏覽器錢包插件如:MetaMask、Temple Wallet、Kukai Wallet都是HD Wallet的一種,必須了解HD Wallet的設計原理才能進一步解決問題。
我們熟知的區塊鏈基礎知識中,一組助記詞可以推導出一組『私鑰』,再用『私鑰』推導出一組『公鑰』,而『公鑰』可以推導出『公鑰哈希』和『錢包地址』,以上推導是單向的,無法反向算出源頭。雖然這樣的構想很棒,但遇到組織架構如:企業、去中心化組織就會遇到:
多人管理一個助記詞很難去歸因資產的管理責任
人員調動、組織擴時充管理權限無法更新
在BIP44的規格被提出來之後:
『私鑰』用有者視同一個節點,可以再去派生子節點
派生採用階層式的架構(見下圖),可以擁有無限層
父節點的『私鑰』擁有者透過派生的機制可以推導出所有的子節點,因此可以向下管理所有子節點的資產
反之子節點的擁有者,只能去派生更下一層的節點,且子節點不能推導回父節點

透過以上特性,最大的受益者肯定是組織架構,這讓他們能夠方便管理區塊鏈資產,但同時又保留了區塊鏈加密的特性。
原先的Python程式碼只要修改以下兩點就好了:
取代Key物件,改用HD Wallet Key物件
使用派生產生『私鑰』,再產生『錢包地址』
from pytezos.crypto.key import Key
from mnemonic import Mnemonic
import numpy as np
incomplete_words = [...]
target_address = "tz1..."
size = len(Mnemonic(LANGUAGE).wordlist)
for position in range(12):
print("======")
print(position)
for index in range(size):
# pick one from world list vector
variable = Mnemonic(LANGUAGE).wordlist[index]
# insert above to an incomplete seed phrase array
input_data = np.insert(incomplete_words, position, variable)
# as string format
input_data_str = ' '.join(input_data)
try:
hdKey = HDKey.from_mnemonic(mnemonic=input_data_str)
sk = hdKey.derive("m/44/1729/0/0")
if(sk.public_key_hash() == target_address):
print(position, index, input_data)
except Exception as e:
pass
但很可惜以上程式碼不能成功執行,因為pytezos還沒支援HDKey物件,所以要改用C#與netezos,這邊不囉唆直接上C#程式碼。
using System;
using Netezos.Keys;
using System.Collections.Generic;
using System.Linq;
string[] lines = System.IO.File.ReadAllLines(@"english.txt");
namespace ConsoleApp
{
internal class Program
{
static void Main(string[] args)
{
var target_address = "tz1..."
for (int i = 0; i < 12; i++)
{
Console.WriteLine("Current Index: ", i);
foreach (string line in lines)
{
var words = new List<string> { ... };
words.Insert(i, line);
var mnemonic = new Mnemonic(words);
var key = HDKey.FromMnemonic(mnemonic, "", ECKind.Ed25519);
var firstchild = key.Derive("m/44'/1729'/0'/0'");
if (firstchild.Address == target_address)
{
Console.WriteLine("");
Console.WriteLine(line);
Console.WriteLine(firstchild.Address);
}
}
}
}
}
}
透過理解BIP44也窺探了組織是怎麼管理區塊鏈資產的,看看Binance在鍊上精美且龐大的資產。

而且不只一個Binance帳號在鏈上活躍著,到底他們是怎麼管理多個帳號,而安全性又在哪裡?這時候新的問題是,實務上如何讓多人管理鏈上資產呢?一些解決方案提供商提出一些想法,不外乎:
分散式的管理
操作者用工具進行操作,而不用錢包操作(因為錢包操作者等同擁有錢包的權限)
權限保管者擁有的是產生『私鑰』的某一環,可以是一段能生成助記詞的工具,且權限保管者看不到工具生成的結果,他的操作等同於蓋章
工具由開發者開發,且角色和操作者、權限保管者分開
尋找外包,讓方案提供商負責安全上的問題
今天的情況比較幸運,所以助記詞在3分鐘內使用ThinkPad T14s筆電很快就算出來了。倘若少了2位註記詞,可能就會需要耗費3分鐘的平方,也就是9個小時,此外助記詞若是順序有問題,使用以上暴力破解想找回助記詞幾乎不可行,最後祝大家都能找回助記詞。
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
https://github.com/baking-bad/netezos/blob/master/docs/docs/wallet-import.md
https://www.riddleandcode.com/blog-posts/what-makes-a-crypto-asset-custodial-solution-right-for-you
https://www.qredo.com/blog/what-to-look-for-in-a-crypto-treasury-management-solution

