电脑随机数是如何生成的?

   不论是维持着你余额宝安全的加密过程还是你在玩《战地4》,电脑都会产生随机数。目前有两类随机数——“真”随机数和伪随机数——两者的区别关乎加密系统的安全度。


  对于随机数的讨论日渐升温,许多人怀疑英特尔内置于各种硬件内的随机数生成芯片是不是靠得住。要理解为什么这种随机数不太可靠,你必须理解随机数的生成原理。

  随机数的作用

  随机数的使用历史已经有数千年。无论是抛硬币还是摇色子,目的是让随机概率决定结果。电脑中的随机数生成器的目的也是如此——生成随机不可预测的结果。

  加密法要求数字不能被攻击者猜到,不能多次使用同样的数字。所以需要一种机制产生攻击者无法预测的数字,这些随机数对加密法至关重要,无论你是加密文件还是访问https协议网站,都需要用到随机数。


  真随机数

  如果电脑是靠代码生成随机数,是不是意味着随机数可以被预测?

  根据随机数的生成原理,我们把电脑随机数分为两类:“真”随机数和伪随机数。

  要生成一个“真”随机数,电脑会检测电脑外部发生的某种物理现象。比如说,电脑可以测量某个原子的放射性衰变。根据量子理论,原子衰变是随机而不可测的,所以这就是宇宙中的“纯粹”随机性。攻击者永远无法预测原子衰变的发生时间,也就不可能猜出随机值。

  举个更实际的例子,电脑会根据环境中的噪音或者采取你敲击键盘的精确时间作为随机数据或熵的生成依据。举个例子,你的电脑监测到你某天下午2点以后敲击键盘的精确时间是0.23423523秒,有足够的这些特定长数字你就能得到一个熵源,也就可以生成“真”随机数。由于人不是机器,所以攻击者无法掌握你的敲击时间。Linux中的/dev/随机设备生成随机数,“阻拦”访问直到熵积累量足够才返回一个真随机数。


  伪随机数

  伪随机数这个概念是相对于“真”随机数而言。电脑通过发送种子数值,运用算法产生某个看起来像随机数的数字,但是实际上这个数字是可以预测的。因为电脑没有从环境中收集到任何随机信息。

  虽然是伪随机数,但是并不是所有领域都不需要伪随机数。比如,如果你在玩电子游戏,那么游戏过程中是靠伪随机数还是真随机数并不重要。另一方面,如果你的应用正在加密,情况就不同了,因为你不希望攻击者能够猜到你的随机数。

  举个例子,如果攻击者掌握了某随机数生成器使用的种子数值和加密算法,如果随机数生成器完全依靠种子数值和加密算法生成密文,这个过程中不添加任何额外随机性,如果攻击者掌握的情报足够多,他们可以逆推来确定加密算法一定会用到的伪随机数,也就能破译密文。


  NSA和Intel的硬件随机数生成器

  为了帮助程序开发者更简单的生成随机数,也为了帮助生成安全的随机数,Intel的芯片组中包括一个硬件随机数生成器,名叫RdRand,这块芯片利用处理器的熵源向软件提供随机数。

  问题是这个随机数生成器是个黑盒,我们不清楚里面的工作原理。如果RdRand藏有NSA的后门,那么政府就可以破译依靠随机数生成器提供的唯一数据产生的密钥。

  这个问题非常严重。在2013年12月,FreeBSD的开发者们取消了对直接采用RdRand作为随机数源的支持,理由是无法信任Intel。RdRand设备的输出结果会用另一套加密算法增加额外熵,确保随机数服务器中即便有后门程序也不会产生影响。Linux已经这么做了,在RdRand的随机数基础上再次进行随机处理,以确保后门程序不可能从中作祟。Intel总裁Brian Krzanich在Reddit上没有直接回答关于是否装有后门的问题。

  当然这不是Intel一家的问题,FreeBSD的开发者们也点了Via芯片的名。从这场争论中我们可以看出为什么不可预测的真随机数如此重要。


  而随机数生成器生成“真”随机数只需要搜集熵或者从真实世界搜集看似随机的数据。对于某些不需要真正随机的应用,随机生成器可能会通过算法和种子数值算出随机数。

时间: 2025-01-21 06:30:59

电脑随机数是如何生成的?的相关文章

声卡数据 读取-通过代码实现读取苹果mac电脑声卡数据,生成音频格式文件

问题描述 通过代码实现读取苹果mac电脑声卡数据,生成音频格式文件 要求:Object C,C语言,C++,java都行,但是要能在苹果电脑上运行,有代码思路也可以交流!

java生成字母数字组合的随机数示例 java生成随机数_java

复制代码 代码如下: package com.test; import java.util.Random; public class GenerateRandomNumber {  public static void main(String[] args) {   System.out.println("生成的10为随机数为:" + getCharAndNumr(10)); }  /**  * java生成随机数字和字母组合  * @param length[生成随机数的长度]  *

win7电脑打开浏览器自动生成TEMP文件夹怎么办

  1.在Win7系统上点击IE浏览器,然后在IE浏览器上点击"工具"-"Internet选项";   2.然后在internet选项窗口上,切换至"常规"选项卡中,然后点击历史记录处的"设置"按钮;   3.历史浏览记录窗口上,查看历史浏览记录和临时文件目录是否指向桌面Desktop文件夹,可以重新设置别的文件夹为系统默认文件夹; 4.点击"移动文件夹"按钮,来浏览临时文件夹,再点击确定按钮保存. 按照上

shell如何生成指定范围随机数与随机字符串

1.使用系统的 $RANDOM 变量 fdipzone@ubuntu:~$ echo $RANDOM 17617 $RANDOM 的范围是 [0, 32767] 如需要生成超过32767的随机数,可以用以下方法实现. 例:生成400000~500000的随机数 #!/bin/bash function rand(){ min=$1 max=$(($2-$min+1)) num=$(($RANDOM+1000000000)) #增加一个10位的数再求余 echo $(($num%$max+$min

C#中获取、生成随机数的三种方法

  这篇文章主要介绍了C#中获取.生成随机数的三种方法,本文讲解了Random 类生成法.Guid 类生成法以及RNGCryptoServiceProvider 类生成法,需要的朋友可以参考下 随机数的定义为:产生的所有数字毫无关系. 在实际应用中很多地方会用到随机数,比如需要生成唯一的订单号. 在C#中获取随机数有三种方法: 一.Random 类 Random类默认的无参构造函数可以根据当前系统时钟为种子,进行一系列算法得出要求范围内的伪随机数. 代码如下: Random rd = new R

android生成随机数-android 中点击按钮生成一组十位随机数怎么做?

问题描述 android 中点击按钮生成一组十位随机数怎么做? 请哪位好心大神指点一下,点击一个按钮生成一组十位随机数,并且显示在输入框中怎么做?求指点菜鸟!!! 解决方案 Html页面中点击按钮发送邮件 解决方案二: 用异步的方法先随机出十个数字然后把它们保存成一个字符串然后在文本框中显示就可以了. 解决方案三: double rd; //随机数 long sws; //生成的10位数 do { rd = Math.random(); sws = (long) (rd*10000000000l

class-关于.net RNGCryptoServiceProvider 生成随机数算法

问题描述 关于.net RNGCryptoServiceProvider 生成随机数算法 关于.net RNGCryptoServiceProvider 生成随机数算法 最近在看 RNGCryptoServiceProvider类 网上都说这个类能产生强随机数 而且大多数帖子都是拿这个类和random函数来比较 我比较疑惑的是这个类生成随机数是用什么算法生成的 具体的算法流程是什么查不到生成随机数的种子是什么也不太清楚 有没有大神知道呢 解决方案 .NET生成随机数C++伪随机数生成算法生成不重

生成不重复的随机数的二种方法

下面我以生成1-10之间的10个不重复的随机数为例介绍生成不重复的随机数的三种方法:1. 通过while循环来实现通过while循环不停的生成随机数,直到生成一个不重复的为止,这种方法比较容易想到,但是效率也比较低下,实例代码如下: static void Main(string[] args) { int[] result = new int[10]; int tmp = -1; Random random = new Random(); bool repeat = false; for (i

Java中生成随机数的实现方法总结_java

在实际开发工作中经常需要用到随机数.如有些系统中创建用户后会给用户一个随机的初始化密码.这个密码由于是随机的,为此往往只有用户自己知道.他们获取了这个随机密码之后,需要马上去系统中更改.这就是利用随机数的原理.总之随机数在日常开发工作中经常用到.而不同的开发语言产生随机数的方法以及技巧各不相同.笔者这里就以Java语言为例,谈谈随机数生成的方法以及一些技巧. 一.利用random方法来生成随机数. 在Java语言中生成随机数相对来说比较简单,因为有一个现成的方法可以使用.在Math类中,Java