如果你常在区块链的世界冲浪,肯定会有一个抱团取暖的社团分享讯息,每当伙伴分享区块链社会事件,如暴力讨债、矿场偷电、名人钱包被盗事件⋯⋯往往是见怪不鲜不能引起你的共鸣,但看到伙伴们钱包被盗的事情,肯定会令大家竖直椅背开始团购冷钱包,或是把电脑、手机的助记词删除改用纸质笔记本。
队友听我分享完点头如捣蒜,随即把所有数字的痕迹都抹除,并将钱包的助记词抄送在纸质笔记本上,然而队友不谙区块链的基础知识,只抄送了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 npincomplete_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的设计原理才能进一步解决问题。
HD Wallet跟你想的不一样
我们熟知的区块链基础知识中,一组助记词可以推导出一组『私钥』,再用『私钥』推导出一组『公钥』,而『公钥』可以推导出『公钥哈希』和『钱包地址』,以上推导是单向的,无法反向算出源头。虽然这样的构想很棒,但遇到组织架构如:企业、去中心化组织就会遇到:
- 多人管理一个助记词很难去归因资产的管理责任
- 人员调动、组织扩时充管理权限无法更新
在BIP44的规格被提出来之后:
- 『私钥』用有者视同一个节点,可以再去派生子节点
- 派生采用阶层式的架构(见下图),可以拥有无限层
- 父节点的『私钥』拥有者透过派生的机制可以推导出所有的子节点,因此可以向下管理所有子节点的资产
- 反之子节点的拥有者,只能去派生更下一层的节点,且子节点不能推导回父节点
透过以上特性,最大的受益者肯定是组织架构,这让他们能够方便管理区块链资产,但同时又保留了区块链加密的特性。
回到问题本身
原先的Python程式码只要修改以下两点就好了:
- 取代Key物件,改用HD Wallet Key物件
- 使用派生产生『私钥』,再产生『钱包地址』
from pytezos.crypto.key import Key from mnemonic import Mnemonic import numpy as npincomplete_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帐号在Tezos链上活跃着,到底他们是怎么管理多个帐号,而安全性又在哪里?这时候新的问题是,实务上如何让多人管理链上资产呢?一些解决方案提供商提出一些想法,不外乎:
- 分散式的管理
- 操作者用工具进行操作,而不用钱包操作(因为钱包操作者等同拥有钱包的权限)
- 权限保管者拥有的是产生『私钥』的某一环,可以是一段能生成助记词的工具,且权限保管者看不到工具生成的结果,他的操作等同于盖章
- 工具由开发者开发,且角色和操作者、权限保管者分开
- 寻找外包,让方案提供商负责安全上的问题
结尾
今天的情况比较幸运,所以助记词在3分钟内使用ThinkPad T14s笔电很快就算出来了。倘若少了2位助记词,可能就会需要耗费3分钟的平方,也就是9个小时,此外助记词若是顺序有问题,使用以上暴力破解想找回助记词几乎不可行,最后祝大家都能找回助记词。
本文链接地址:https://www.wwsww.cn/qianbao/23189.html
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。