助记词掉了如何找回?以Tezos为例子

如果你常在区块链的世界冲浪,肯定会有一个抱团取暖的社团分享讯息,每当伙伴分享区块链社会事件,如暴力讨债、矿场偷电、名人钱包被盗事件⋯⋯往往是见怪不鲜不能引起你的共鸣,但看到伙伴们钱包被盗的事情,肯定会令大家竖直椅背开始团购冷钱包,或是把电脑、手机的助记词删除改用纸质笔记本。

队友听我分享完点头如捣蒜,随即把所有数字的痕迹都抹除,并将钱包的助记词抄送在纸质笔记本上,然而队友不谙区块链的基础知识,只抄送了11位助记词!找寻那遗失的1位的过程正是本文要分享的。

确认可能性并使用程式计算遗失的那一位

硬干程序之前,必须先确认规格,才能衡量这个硬干的可能性,Tezos如其他热门的加密货币,如:Ether、Bitcoin一样,使用BIP39的规格设计助记词,这里有一些重点帮大家浓缩:

  1. 助记词其实就是由2048个不同的单字组成,每一个单字对应一个二进制号码,从到0x00000000000,0x11111111111对整个表格有兴趣请移驾这里
  2. 首四位不会重复,如:642号expand与643号expect只有三位重复,为的是避免助记词在抄送的过程中出现笔误的现象。
  3. 支持多种语言,如:英文、日文、韩文、西班牙文、简体中文、繁体中文、法文、意大利文、捷克文、葡萄牙文都可以有助记词,但目前大多数钱包都是使用英文助记词。

透过以上的推理,只需要从表格中取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链上活跃着,到底他们是怎么管理多个帐号,而安全性又在哪里?这时候新的问题是,实务上如何让多人管理链上资产呢?一些解决方案提供商提出一些想法,不外乎:

  • 分散式的管理
  1. 操作者用工具进行操作,而不用钱包操作(因为钱包操作者等同拥有钱包的权限)
  2. 权限保管者拥有的是产生『私钥』的某一环,可以是一段能生成助记词的工具,且权限保管者看不到工具生成的结果,他的操作等同于盖章
  3. 工具由开发者开发,且角色和操作者、权限保管者分开
  • 寻找外包,让方案提供商负责安全上的问题

结尾

今天的情况比较幸运,所以助记词在3分钟内使用ThinkPad T14s笔电很快就算出来了。倘若少了2位助记词,可能就会需要耗费3分钟的平方,也就是9个小时,此外助记词若是顺序有问题,使用以上暴力破解想找回助记词几乎不可行,最后祝大家都能找回助记词。

本文链接地址:https://www.wwsww.cn/qianbao/23189.html
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

相关文章阅读