2014年12月8日,blockchain.info再爆问题,由于小太一直忙着开发新版本,没顾上细看,大概想了想,应该还是随机数问题,也就没再关注。
昨晚开始,有用户在比太官方群问到此次事件的原因,币界上也有人希望小太能说说,没办法,小太只好抽空做做功课,尽量搞明白到底发生了什么。
关于此次事件,国外还算专业,老外的讨论还是集中于“不安全的随机数导致R值重复,进而导致暴漏私钥”的范畴,国内的讨论就有些不在“点”上了,比如说,有人认为blockchain.info是把用户的私钥给误删了,还有人认为是counterparty引发的问题。
这些说法其实都不对,哪怕是老外,也只是把一年多以前讨论“R值重复”的话又翻出来说了一次而已。
据说,导致此次问题的是blockchain.info的这次改动:
https://github.com/blockchain/My-Wallet/commit/ae203bf010446e0ba4d40e5744fcc6ae68a86055单纯看这个commit里的改动,虽有问题(blockchain.info一直都有随机数问题),但不应爆发(两个半小时内的随机数都有问题),这也是为什么连Gmaxwell、Peter Todd等比特币核心开发者都没能准确定位问题的原因。
那是因为,blockchain.info写错的代码并没有出现在版本历史里,而是被他们给“force pushed over”了,也就是说,您已经无法知道那两个半小时里blockchain.info网站上运行的程序到底是什么样子的。
比较可能的情况是,在他们更新随机数算法时,漏掉了rng.js的第29行“rng_pptr = 0;”,即未对这个变量做初始化操作,这样会导致什么后果呢?
我们写了一小段js程序测试了一下(
https://github.com/bither/analyze/blob/master/analyze-blockchain-info-20141208/rng_test.js),发现,结果会是随机数熵池里只会有一个字节的元素,然后拉伸成Int32,这显然远远小于比特币256位随机数的要求,在熵池中取出的数据长度小于256位的情况下,blockchain.info会用一个算法来对种子进行拉伸,拉伸到256位。拉伸算法本身不重要,最重要的是,这使得随机数的结果只有256种可能,即:0-255。也就是说,在这两个半小时里,所有使用blockchain.info钱包的用户,无论是生成私钥,还是签名交易,都使用了一个范围只有256的随机数。
看到这里,读过小太随机系列文章的人可能就会明白,所有这些用户的私钥都已经暴漏,任何人都可以很轻松的遍历这256个数,得到这些私钥,这才是blockchaini.info爆发本次随机问题的根本原因。
多亏了白帽子johoe,他保护了大部分比特币,避免了blockchain.info及相关用户的进一步损失,向白帽子致敬!!!
补充一点,blockchain.info的随机数问题一直存在,这次事件已经不能算是随机数问题了(256个固定的数字能叫随机数吗?)。而且,我们还应给blockchain.info的随机数“improvements”打上双引号,看过代码您就知道了,他们这次把Math.Random()提到了外面,也就是说,其实是更差了,而不是更好了。
blockchain.info给这次问题的解释含混不清,这种含混也导致了各种混乱的报道,而且,他们最终还删除了github版本库上的记录(只能通过commit hash找到),他们没有说清楚问题的原因(也许他们自己也不确定影响程度),这种态度对于用户是不负责任的。
作者:比太钱包
官方微博:@比太钱包
http://weibo.com/bither官网:
http://bither.net捐赠地址:1BsTwoMaX3aYx9Nc8GdgHZzzAGmG669bC3