生成*真*随机数是很困难的一件事情。一般各种语言里面提供的 `random()` 函数都是生成的伪随机数。`random()`的底层实现实际上是一个数学公式,例如,这个公式接收一系列初始值,然后根据这个初始值就可以生成一个数列,每次`random()`函数获取的随机数,不过是取这个数列中的一项。伪随机数的安全关键点在于,初始值的选择,一旦别人猜出你的初始值,就可以知道你后面要生成的所有伪随机数。
有很多人初始化随机数种子喜欢使用当前时间戳,但是要注意使用这种方式生成的随机数不能用于安全相关的场景,例如用它来生成每期的中奖号码。黑客可以根据的使用的编程语言,知晓伪随机数的公式,然后根据你大概的执行时间,来尝试初始化这个公式,根据历史号码对比,得出你使用的初始化时间戳,从而获得以后的中奖号码。
为了使伪随机数不可预测,选择合适的初始化参数至关重要,初始化参数要不可预测,也就是说要*真*随机。一般来说安全的方式是使用`/dev/random`( Linux 系统)设备产生的随机字节数据。`/dev/random`中的数据来源于计算机硬件设备的环境噪声,例如放大电路的热噪声,因此`/dev/random`中的数据非常非常难以预测,接近于*真*随机数,各种编程语言中大部分涉及加密的函数库,初始化参数都会用到`/dev/random`的数据。
不过`/dev/random`在虚拟机环境下可能不是十分安全,例如在 AWS、阿里云这种云平台场景下,所有的虚拟机设备都是虚拟化出来的,导致`/dev/random`的数据可能会被猜测出来。这中情况下需要考虑别的*真*随机数生成方式,例如专门的随机数生成硬件设备,或者使用像
random.org 这样的服务,
random.org 的随机数据来自于地球的大气噪声。