随机数的安全问题

今天聊一聊随机数的安全问题。随机数在平常的开发过程中应用非常的广泛,但是很少会引起开发人员注意其安全性。
我们先简单回顾下随机数:

一:随机数分类
真随机和伪随机;伪随机又分为强伪随机和弱伪随机。

1.真随机数
真随机数通常通过物理过程得出,比如噪声、光电效应等。这种一般是通过硬件随机器得出,硬件随机器通常是由换能器、放大器和模拟数字转换器组成;换能器将物理过程转换为电信号,放大器将其随机扰动的振幅放大到宏观级别,最后由模拟数字转换器用来输出具体的数字。

2.伪随机数
伪随机数通常是一定的算法和种子算出来,软件实现的都是伪随机。
强伪随机数,就是比较难预测的随机数;弱伪随机数,通常是一种固定的算法和种子,比如星际争霸里面应用的战斗随机种子。

二:随机数的特性
1.随机性
完全杂乱的数列

2.不可预测
无法推导;无法从原来的数列推导出新的数列

3.不可重现
无法重现之前的数列

三:随机数的应用范围
随机数的应用范围太广了,大概罗列一些
验证码
抽奖
UUID
Token
密码
游戏
洗牌
战斗释放
Rougelike游戏

四:随机数带来的安全问题
如果在使用随机数的场景中,我们使用了弱伪随机,那么可能会被暴力破解。
假设在一个扑克牌游戏里面使用了时间作为种子的弱伪随机数,攻击者就可以根据你使用的语言去找到对应的随机函数,传入对应的时间,这样可以将所有人的牌全部算出来。同理在抽奖、验证码获取这些场景使用弱伪随机也会有同样的问题。

就算用弱伪随机,那么也请不要用时间座位随机数的种子,稍微复杂一点,加上不可预测的值作为参数计算一个Hash值或者通过其他加密算法计算出一个中间值作为种子。

弱伪随机数和强伪随机数最大的区别在于不可预测,时间是一种可以预测是值。
玩家的手指触点、鼠标的当前位置坐标这些都是不可预测是值,都可以作为参数。

我们使用真随机的机会会比较小,但是我们可以使用强伪随机,网上有一个网站(https://www.random.org/)通过大气噪音提供真随机数,你也可以试试。

解决随机数的安全问题核心还是在于随机数自己的3个特性:随机性、不可预测、不可重现。
希望随机数的安全问题能引起大家的重视,关于随机数出现的安全问题太多了,去年区块链项目也爆过一次,大家有兴趣可以网上搜索一下。