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

ChainShell
ChainShell 机构得得号

Nov 27, 2018 链壳科技是专业提供身份认证、密钥管理和整体安全解决方案服务商

摘要: 近期区块链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(&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机制能继续正常运行。

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

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

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

(作者:ChainShell,内容来自链得得内容开放平台“得得号”;本文仅代表作者观点,不代表链得得官方立场)

链得得仅提供相关信息展示,不构成任何投资建议
本文系作者 ChainShell 授权链得得发表,并经链得得编辑,转载请注明出处、作者和本文链接

更多精彩内容,关注链得得微信号(ID:ChainDD),或者下载链得得App

分享到:

相关推荐

    评论(0

    Oh! no

    您是否确认要删除该条评论吗?

    分享到微信