使用NODEJS解密bitshares网页钱包备份文件

有一位我的博客读者,问了我一个问题,比特股钱包的密码忘了,想写一段程序暴力破解,可是没有找到相关的代码和调用方法。我带着这个问题,去代码里面找了找,写了一段 简单的程序 ,本文阐述一下这段程序的逻辑。

其实主要的逻辑在19~61行,也就是函数decryptWalletBackup,是从bitshares-ui拷贝出来的(请看18行注释)。这个函数接受两个参数,backup_wif和backup_buffer。前者是wif格式的私钥(参考 这篇博文 ), 后者是钱包备份文件(.bin)的内容。backup_wif怎么来的呢?参考第71行,是密码的确定性函数。

decryptWalletBackup函数的调用在74行,如果密码正确,75行console.log会被调用,否则,76行console.error会被调用。如果用nodejs来做暴力破解,不断的修改密码看看decryptWalletBackup这个函数是否能resolve promise即可。

其实,代码解析到这里,也许读者朋友会觉得很无趣,因为这个解析显得有些简单了。那么,难在什么地方呢?一般来说,知识不难,获取知识并应用的过程比较难。授人以鱼,不如授人以渔 : 具体来说本文尝试回答两个主要问题,并在阐述第二个主要问题时提出两个小问题和我的思考。

第一个问题,如何从开源代码中快速准确找到需要的功能?这其实是一个代码阅读的方法问题。我的回答: 要从代码中重建作者的逻辑框架,并进行层次合理的抽象 。就一个特定问题来说,当一个人不知道从哪里去找相关代码的时候,需要整体理解代码的框架,然后针对性的阅读感兴趣的部分,并且按照自己的理解去做局部测试。就好比玩乐高积木, 别人搭好的建筑,我们需要局部借鉴并且建一个新的,做法就是恰好把需要的局部拆下来,再重新搭。比如本文讨论的问题,要本地暴力破解,想知道代码在哪,那么首先得大体理解 bitshares-ui 代码整体的结构:

  • 知道这是一个基于React(package.json里面的依赖,以及源代码里面有很多jsx文件)和Webpack(package.json里面的各种快捷命令)的项目

  • 下层依赖什么库?从 package.json 里面看

  • bitshares-ui代码结构?看子目录,需要大体理解 React的组件编程方法论

  • 从顶层组件开始,大体理解代码和使用网页钱包的关系

从这个角度出发,根据目标分解,逐步的去找,就能找到想要的任何组件以及其调用的任何库的方法。

第二个问题,如何控制抽象级别并且避免陷入细节?这个问题比第一个问题更具体一些,需要时常锻炼。回答第一个问题时说到的“合理的抽象”,也是一个意思。与盲人摸象一样,其实如果每个盲人关注大象的每一个局部,只要目标允许,就是合理的,关键需要理解自己所关注的局部和整个大象的关系,不把局部代替为整体就好。 研究代码,并不需要一下子把所有的部分都搞明白才能修改或者使用局部代码,从代码整体的结构往下看,一级一级找下去,找到能满足目标的可能解决方案,就放手去验证,并通过实际操作反馈,调整自己的逻辑假设,重新验证,这样反复迭代几次,可迅速完成目标。经常训练的话,迭代次数可为个位数。其实,我本人并没怎么学过和使用过 React,但并不妨碍 我从总体上理解React的组件编程模型,也不妨碍我从大型React项目(bitshares-ui)中找到感兴趣的部分(网页钱包备份解密方法)并加以利用。关注目标,通过抽象来隐藏细节,理清组件之间的接口关系,是关键。我这里列举2个小问题并给出我的思考,也许读者就更好理解了。

小问题1:如何使用其他编程语言(C++/Python/Go)来解密网页钱包?由于这个问题的上下文与本文讨论的主要问题不一样,因此需要的知识也不一样了。要自己实现的话,需要从bitsharesjs库内部,理解网页钱包的格式、压缩和加密方法,并从其他编程语言将这些逻辑重组。问题是,如果没有这样一个目标,就无需理解这么多, 直接理解前文的接口调用即可。

小问题2:网页钱包备份的格式怎么样的?这个问题可从问题1派生。我的答案是,我不甚了解,但如果有需要的话,可以分N层去解释。可以肯定的是,网页钱包的前33个字节为一个临时公钥的二进制形式,后面是AES加密存储的内容。在这个AES加密内容中,必定有一部分与前面的公钥相关,使得解密过程可以直接判断密码是否正确。这个结论是我从 bitshares-ui中的那个文件中的代码推导出来的,但是更细节的结构,例如解密过程怎么验证密码的正确性,就得研究bitsharesjs库中 AES.decrypt_with_checksum的实现了。

好,本文到此结束,感谢看到这里的朋友。如果你有任何问题,欢迎联系我,也许我能帮你解决一个问题,并同时分享些心得给更多的朋友。