一位朋友在去年9月4日的时候参与ico.info,网站关闭前夕把1万个EOS提到imtoken钱包,备份了keystore文件,可是不知道还要备份密码,现在只能看到钱包里面的币,可惜取不出来。6月1日EOS主网即将上线,如果再想不起来密码,这些EOS就将永远沉睡在以太坊的区块链里。
区块链的世界里私钥就是一切,以太坊的keystore相当于加密过的私钥,它采用了对称性加密算法,如果不知道密码的特征,用普通的电脑穷举所有的8位字母和数字的排列组合,也得花费相当长的时间。
我自告奋勇揽下了这项任务,因为我知道每个人设置密码时都有一些特殊的习惯,并且很少使用超过8位的密码,对于这样的情况,暴力搜索的范围会大幅缩小,仍有一线希望找回密码。
KeyStore加密原理
以前只知道keystore把私钥加密处理后保存为一个文本文件,但背后的技术细节并没关注。这次拿到朋友的keystore文件之后,马上开始研究keystore的加密存储方式,网上的一篇文章比较详细地介绍了keystore的加密存储原理(https://ethfans.org/posts/what-is-an-ethereum-keystore-file)。keystore是一个json字符串,里面最重要的是crypto信息。
"crypto" :
{
"cipher" : "aes-128-ctr", //对称 AES 算法的名称
"cipherparams" : { // 加密时用到的参数
"iv" : "83dbcc02d8ccb40e466191a123791e0e"
},
"ciphertext" : "d172bf743a674d.....4e6ad2fbde479c", //加密后得到的字符串
"kdf" : "scrypt", //密钥生成函数
"kdfparams" : { //上面kdf需要的参数
"dklen" : 32,
"n" : 262144,
"r" : 1,
"p" : 8,
"salt" : "ab0c78760.....43190334ba19"
},
"mac" : "2103ac29920d71.....56c331e3097" //用于验证密码是否正确的代码
}
整个过程还是蛮复杂的,有一张图说明了整个过程,非程序员和黑客可以忽略这张图。这里有一个重要的细节,mac信息可以用于校验密码是否正确,从而可以快速地(几秒之内)判断一个密码是否准确无误,可以节省大把的尝试时间。
图片取自ethfans.org
以太坊密码恢复工具pyethrecover
李笑来说过“你并不孤独”,世界上肯定有人与你有同样的遭遇,程序员们非常忌讳重复发明轮子,写代码之前先用google搜索一下,马上发现了pyethrecover这个工具(https://github.com/ryepdx/pyethrecover)。这段python程序能够根据你给出的密码片段的特征,生成一个包含所有组合的密码本,然后用程序一个一个地尝试这些密码。
正好以前学过python,按照github原作者的介绍,该程序可以运行在python 3环境中。可是在我实际安装时,某一个依赖的类库遇到了setup.py脚本无法执行的问题,折腾几次后,又找了另外一个github源程序,仍然无法正确安装。初步判断是windows环境的原因,准备切换到Linux环境中再试试。
.NET环境中的以太坊编程工具Nethereum
#p#分页标题#e#我对Linux环境不熟,对C#更加熟悉,看看.NET平台上有没有可以借鉴的类库可用?网上很快就发现了Nethereum,网址:,这个类库相当强大,RPC、钱包与智能合约等功能都支持,这些功能暂时与我要解决的问题无关,我发现了Nethereum.KeyStore这个名字空间,与密码有关的功能应该在这里。
Nethereum的文档写得不全,找了半天才找到下面这2条关键性的语句,可以通过keystore和password计算出来私钥。
KeyStoreScryptService svc = new KeyStoreScryptService();
return svc.DecryptKeyStoreFromJson(password, json);
我掏出自己的imtoken钱包,用我的keystore文件测试了一下,当密码正确时,程序能得到正确的私钥;当密码错误时,上面的第二行语句会抛出异常。稍微完善一下代码,一个简陋的以太坊暴力破解工具就有了。
我询问朋友的密码特征,他回忆说,平时密码大概会分为三部分,里面有字母、特殊字符和数字,常用的单词大概有7个,特殊字符大概有3种,数字大概也有7种,首字母有可能大写,这些片段全部排列组合之后也就不到500种可能性,看来有戏。
根据朋友提供的这些密码特征,快速用几个循环语句生成了一份密码本,开始暴力遍历破解。可能Nethereum类库没有优化,尝试一个密码有点慢,需要2~3秒左右,不过这都不是问题,优化代码的事情以后再说,500条密码很快就尝试完了,很遗憾,并没有找到密码。
GPU能加速吗?
之后的几天一直忙于办理工作调动手续,到了北京之后还要租房子,但心里一直惦记着这个暴力破解程序。在北京给我接风的是一位著名的黑客,喝酒之间聊到了这10000个EOS的话题。
这位黑客朋友对Linux非常熟悉,保持着变态的安全习惯,密码都在20位以上,从来不用网站上提供的钱包安装文件,非要自己亲手用源代码编译生成一份执行文件!
这个问题勾起了他的兴趣,第二天酒醒之后,他马上去查找GPU加速算法,准备挪出30块挖矿的显卡来一场破解大战。一天之后他扔给我一张图片,说这个加密算法太变态了,一块1060的显卡如果想利用全部内核需要消耗80GB的内存!!!
GPU这条路被堵死了,看来纯粹的暴力破解是没希望了。
再试密码本
现在又回到了原来的思路上,以现在程序的速度,2~3秒尝试一个密码,离6月1日不到1周,如果算法没有优化,这几天1台机器日夜不停地计算,最多只能尝试30万个密码,而长度为8的字母、数字与特殊字符的全部排列组合高达40^8种可能性,大概有6万亿个密码。
找房子期间我仍惦记着破解密码的新思路,与同去看房的同事随口聊起这件事,她又提供了几条不一样的思路:
“那位朋友在北京吗?当面问一下当时操作钱包时的一些细节”
“让朋友当场注册一个新的imtoken钱包,看看有什么操作习惯”
“再回忆一下常用的8位密码,增加一点希望”
回到宿舍,先从网上找到密码生成工具passmaker,准备更新密码规则,生成一份更为全面的密码本,然后分工到几台机器上分布计算。
另外,再次打电话让朋友仔细回忆当时设置密码时的细节,这次朋友提供了一个最有可能的8位密码。此时已经晚上23:00了,passmaker仍在下载中,我还没有洗澡,也感觉有点累了,不管那么多了,把最新得到的密码线索放到原来的程序中,运行!洗个澡再说。
洗澡出来,看了一眼屏幕,有点不敢相信自己的眼睛。
已经破解!!!!!!!!
【编辑推荐】
1分钟了解“区块链分叉”的本质
外媒速递:关于区块链技术的13种认识误区
区块链的未来已至?绝对的去中心是不成立的,看完这篇你就懂了
一首《凉凉》和《泡沫》,送给区块链鼓吹者
厌倦了口令?用区块链吧