​浅析区块链DApp安全随机源机制的设计与实现区块链

ChainShells 2018-11-27 13:42
分享到:
导读

近期区块链DApp游戏的应用数量和用户数量都得到了一定增长,但令人担忧的是多款竞猜类DApp频频爆出被黑客进行了针对随机数缺陷的攻击

近期,区块链DApp游戏的应用数量和用户数量都得到了一定增长,这对公链的应用探索和推广有积极的促进。令人担忧的是,多款竞猜类DApp频频爆出被黑客进行了针对随机数缺陷的攻击。攻击成功后,黑客就能够预知竞猜结果,来获得下一次竞猜的奖励。

在中心化的竞猜类应用里,竞猜结果都是由中心提供的,参与竞猜的客户端向中心服务提交竞猜订单,中心收集竞猜订单并生成竞猜结果返回给客户端。在这个过程中,客户端只负责收集竞猜订单和通知结果,并不参与竞猜结果的计算。竞猜结果都是由中心产生竞猜用随机数,根据游戏规则将随机数的随机性体现在竞猜结果上。通过这样的随机数转化来保证竞猜结果的随机性和公平性。因此竞猜应用是否公平、中奖机率是否随机,完全取决于随机数的生成、使用过程是否完全实现了的随机性的传递。

在区块链的DApp应用里,随机数或由第三方随机数服务接口利用Oracle机制,由硬件HSM生成后提供给区块链参与者,或由智能合约提供生成规则后DApp自行生成。大多数DApp使用的都是由智能合约进行共识来生成伪随机数。

目前,ETH和EOS等公链并未提供可靠的伪随机数接口。一些热门的DApp游戏尤其是竞猜类游戏如Luckyos、EOS.WIN、EOSDice等先后因伪随机数生成的缺陷而遭到黑客攻击。我们以EOSDice举例来说明攻击的原理。

-------------------https://github.com/loveblockchain/eosdice/blob/v3.0/eosbocai2222.hpp--------------------

    uint8_t random(account_name name, uint64_t game_id)

    {

        auto mixd = tapos_block_prefix() * tapos_block_num() name game_id - current_time();

        const char *mixedChar = reinterpret_cast<const char *>(&mixd);

        checksum256 result;

        sha256((char *)mixedChar, sizeof(mixedChar), &result);

 

        uint64_t random_num = *(uint64_t *)(&result.hash[0]) *(uint64_t *)(&result.hash[8]) *(uint64_t *)(&result.hash[16]) *(uint64_t *)(&result.hash[24]);

        return (uint8_t)(random_num % 100 1);

    }

----------------------------------------------------------------------------------------------------------------------------------------

  从最新修复后的代码可以看到,该随机函数中使用的随机因子(seed)主要是:
     tapos_block_prefix() * tapos_block_num()  --参照区块信息
   name                                      --账户名
     game_id                                   --账户名
   current_time()                            -- 当前时间

在该版本中,下注账户余额(pool_ol_eos.amount) 已经不参与随机因子(seed)。项目方解决被攻击的思路是避免黑客通过可控制的账户余额(pool_ol_eos.amount)来计算随机因子(seed)。但该修复只是减少可控因素的成本,随机因子中的账户名(name)还是可以被操纵的。当下注金额较大时,黑客依然有十足动力来进行攻击。

从安全本质上来说,能够被黑客轻易攻击是因为这个随机数算法不具备工业级别。表现为:

1.作为随机因子的(seed)的熵源(Entropy Input)不是可靠。

2.随机因子Seed的安全强度不足。

3.算法简单和重置随机因子机制缺失,随机数结果可回溯且具备可预测性。

如何设计和运用具备工业级别的伪随机数方案,笔者建议参考2015年 的NIST 800-90A《确定性随机比特生成器的随机数生成方法建议》(‘Recommendation for Random Number Generation Using Deterministic Random Bit Generators’),它给出了实践和参考的一些实现方法。但结合DApp的业务流程时,也需要进行针对性的调整。NIST的800-90A 2016年版本也曾造成了重大的安全事故:建议中包含了4种随机数生成方法,其中一种Dual_EC_DRBG算法为美国安全局进行全球的通讯窃听提供了有力的助攻。

该建议书中的DRBG(Deterministic Random Bit Generators)机制有五个独立的功能:

1.实例化功能(instantiate function)获取熵源(entropy input)或者附加 随机数Nonce和个性化字符串(personalization string)创建初始内部状态的随机因子(seed)。

2.随机比特位生成功能根据请求使用当前内部状态(current internal state)和可能的附加输入(Additional Input)生成伪随机比特位; 并生成下一个请求的新内部状态(new internal state)。

3.重设随机因子功能(Reseed Function)获取新的熵源,并将其与当前内部状态(current internal state)和可能的附加输入(Additional Input)结合创建新的随机因子(new seed)和新内部状态(new internal state)。

4.注销实例化功能将内部状态清零擦除。

5.自检功能确定DRBG机制能继续正常运行。

image.png

图片来源:NIST 800-90A《确定性随机比特生成器的随机数生成方法建议》

在开源世界里,已经有很多满足NIST要求800-90的DRBG的实现,笔者建议在不具备密码学基础的Developer不要轻易的编写自定义的伪随机数生成器。

即使采用满足标准的伪随机数生成器,但由于伪随机数生成算法跟设备上物理状态或执行过程中状态相关,在区块链分布式系统的各个Node无法得到一致的随机数。 在区块链世界里某些应用场景尤其是有奖竞猜等,各个Node所需要的随机数(不管是真随机还是伪随机)应该是可共识的,可信赖的,可验证且可审计的。

链壳科技愿为DApp开发者提供全方位的安全设计咨询和审查服务,共同提高产品抵御攻击的能力,为用户提供良好的安全体验。合作请联系:business@chainshells.com


随机数 随机 生成 因子 竞猜
分享到:

1.TMT观察网遵循行业规范,任何转载的稿件都会明确标注作者和来源;
2.TMT观察网的原创文章,请转载时务必注明文章作者和"来源:TMT观察网",不尊重原创的行为TMT观察网或将追究责任;
3.作者投稿可能会经TMT观察网编辑修改或补充。