无处不在的随机数

目录:

  • 什么是随机数
  • 随机数分类
  • 伪随机数生成器
  • 真随机数生成器
  • 各种语言中的随机数
  • 使用系统时间作为种子是否安全

什么是随机数

参考维基百科随机数
随机数的随机性检验可以分为三个标准:

  1. 统计学随机性。 统计学伪随机性指的是在给定的随机比特流样本中,1的数量大致等于0的数量,同理,“10”“01”“00”“11”四者数量大致相等。
  2. 密码学安全伪随机性(不可预测性 )。 其定义为,给定随机样本的一部分和随机算法,不能有效的演算出随机样本的剩余部分。
  3. 真随机性(不可重现性)。 其定义为随机样本不可重现。除非将数列本身保存下来,否则不能重现相同的数列。

随机数分类

类型 统计学随机性 不可预测性 不可重现性 备注 是否可用于密码技术 生成器
伪随机数 Χ Χ 只具备随机性 Χ 伪随机数生成器 PRNG (Preudo Random Number Generator)
密码学安全的伪随机数 Χ 具备不可预测性 密码学伪随机数生成器 CPRNG (Cryptography secure Preudo Random Number Generator)
真随机数 具备不可重现性 真随机数生成器 TRNG (True Random Number Generator)
真随机数是否存在?

真随机数是否存在这是一个有争议的问题。
下面是维基百科的一段话:

实际上只要给定边界条件,真随机数并不存在,可是如果产生一个真随机数样本的边界条件十分复杂且难以捕捉(比如计算机当地的本底辐射波动值),可以认为用这个方法演算出来了真随机数。 但实际上,这也只是非常接近真随机数的伪随机数,一般认为,无论是本地辐射、物理噪音、抛硬币……等都是可被观察了解的,任何基于经典力学产生的随机数,都只是伪随机数。

但是本文这里把本地辐射、物理噪音、抛硬币这种,认为是真随机数,下面所说的真随机数都是指这些。

伪随机数生成器

伪随机数生成器是由外部输入的种子和内部状态两者生成的伪随机数列。


image

生成伪随机数有以下几种算法:

  • 线性同余法(非密码学安全)
  • 单向散列函数法(密码学安全)
  • 密码法(密码学安全)
  • ANSI X9.17(密码学安全)

1. 线性同余法

线性同余法就是将当前的伪随机数值乘以 A 再加上 C,然后将除以 M 得到的余数作为下一个伪随机数。

R0 = (A * 种子 + C) mod M
R1 = (A * R0 + C) mod M
R2 = (A * R1 + C) mod M

Rn = (A * R(n-1) + C) mod M

线性同余具有周期性,根据周期即可预测未来的状态。所以它不是密码学安全的伪随机数。

C 语言的库函数rand,以及Java的java.util.Random类等,都采用了线性同余法。因此这些函数都不能用于密码技术。

2. 单向散列函数法

单向散列函数也可以生成不可预测的伪随机数,且为密码学安全的伪随机数(因为它的单向性,具备不可预测性)。


image

3. 密码法

使用密码法也能生成密码学安全的伪随机数,既可以使用 AES 对称加密,也可以使用 RSA 公钥加密。


image.png

4. ANSI X9.17

用 ANSI X9.17 方法也可以生成密码学安全的伪随机数。


image.png

真随机数生成器

/dev/random和/dev/urandom是Linux系统中提供的随机伪设备,这两个设备的任务,是提供永不为空的随机字节数据流。
这两个设备的差异在于:

  • /dev/random依赖于系统中断,系统的中断数不足时,/dev/random设备会一直封锁,尝试读取的进程就会进入等待状态,但 /dev/random设备的随机性很高。
  • /dev/urandom 不依赖系统的中断,也就不会造成进程忙等待,但是随机性不高。
    Windows操作系统的CryptGenRandom接口提供类似的功能。

各种语言中的随机数

java

  • java.util.Random() / Math.random() / java.util.concurrent.ThreadLocalRandom ():使用线性同余方法,是非密码学安全的随机数。
  • java.Security.SecureRandom:产生的是密码学安全的随机数。
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");  //通过hash算法产生密码学安全的伪随机数

同时也可以用NativePRNGBlocking或NativePRNGNonBlocking方法(NativePRNGBlocking使用/dev/random;NativePRNGNonBlocking使用/dev/urandom)


image.png

C/C++

  • rand():线程不安全,线性同余算法->可以预测
  • Random_device: c++11,不可预测,读取dev/urandom或调用RtlGenRandom作为随机源

使用系统时间作为种子是否安全

随机数的种子,决定了随机数的安全性。
如果只是使用系统时间作为随机数的种子,是不安全的:

  • 同一时间启动的并发进程将会生产一样的随机数。
  • 一天只有86400秒,即使爆破也很容易。

我们应该使用真随机数作为伪随机数的种子,例如java中,无参构造函数实例化SecureRandom,默认的算法是“nativePRNG”,就是从/dev/random获取随机数。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容