浅谈随机数与网络安全与熔岩灯

2022-08-11 14:43:38 浏览数 (1)

上周,阅读了我司入职的安全培训课程,其中提到的随机数部分内容,看完之后觉得很有意思,就又读了几篇相关文章,总结成本文,希望你也能喜欢!

真伪随机数


要说随机数,首先我们得分清,什么是真随机数,什么是伪随机数。

真随机数,指的是那些只使用了物理来源产生的数字。所谓的物理来源,指的是例如宇宙背景辐射,外界噪音等等,纯物理的产生器。然而,不是所有的公司和个人,都能搞一个天文台天天监测宇宙背景辐射,这样的获取随机数的流程也过于折腾了一些。

在软件工程中,我们需要更方便更快的随机数产生器,于是,使用一定的物理来源和软件计算相结合,伪随机数诞生了。

我们的冯诺伊曼老爷爷就曾经设计了一个简单的名为Middle Square随机数产生器,它首先选择一个seed数字,然后对seed进行平方,取结果的中间几位数,作为计算产生的随机数,之后再对这个数进行平方,得到再下一个结果,如此反复。

举个例子:

如果你选择4181作为算法的seed,那么,4807,1072,1491…就会是你得到的一串随机数,具体计算过程如下:

Randomnumber

Its Square

MiddleDigits

4181

17480761

4807

4807

23107249

1072

1072

1149184

1491

and so on

...

...

这个简单的伪随机数算法其实是很容易预测的,因为它的下一个随机数完全是由上一个数字计算得来的,随后取代它的Mersene Twister算法在计算过程中,还加入了一些中间状态,导致结果更加难以预测。不过,冯诺伊曼爷爷还是给我们举了个好栗子,况且连他自己也说过:

"Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin."

因此,即使是伪随机数,也应该符合以下要求:

1. 数字出现的概率随机,分布均匀,互相独立

2. 使用已知的随机数序列,无法推测出之后产生的随机数

仅仅如此就够了吗,只要有满足这样要求的算法存在,我们就可以高枕无忧了吗?

还不够!来看看一次脆弱的伪随机数生成器,导致的年会中奖新闻吧~

随机数与年会中奖

当我和Mars还在一家公司上班的时候,某年年会第二天的部门大会,一群程序员们懒懒散散的一大早爬起来开会,熬了一上午,终于等到了抽奖的时刻。部门大会的奖虽然不如第一天年会晚宴的时候多,但价值依然很给力,所有人都满怀期待的等着抽中自己。

然后,奇妙的事情就发生了。连续几个中奖的人,都是前一天晚宴时候中过奖的!第一个人出现的时候,大家都赞叹他绝佳的运气,等到第三个第四个,大家坐不住了,纷纷表示这抽奖的系统绝对的有问题,连CTO也看不下去了,当场和大家一起review了抽奖的代码,导致之后网上出现了一大波与此相关的段子和新闻。

所以到底发生了什么呢?

原来,写这段抽奖代码的小哥,在希望随机抽取一个工号的时候,使用了伪随机数。他使用一个数字作为seed,然后在这个基础上一次次计算下一个随机数。根据前面对随机数的介绍,之后的数字是否随机,很大部分取决于seed是否随机,否则你上次算和下次算,结果不都一样吗。

然而,小哥就真的偷懒了,他每次都使用了同一个seed,导致关机重新运行之后,抽出来的还是那一拨人!要知道,计算机逻辑可是根据代码无差错的执行,它可不知道什么是随机,只知道准确无误。

这就是一个脆弱的随机数产生器的例子,重启一次,一切重演。即使之后产生的数字均匀分布,难以预测,可是显然,只要没有一个好的seed,一切都白搭。

在review完代码之后,有同事给写这段代码的同事提出,应该使用开始使用算法时候的时间戳来作为seed!要知道,每次开始计算的时间都是不一样的,使用时间戳,不就可以保证了seed的随机了吗!

时间戳真的那么安全吗?这又要讲到一次针对伪随机数的网络攻击~

一次针对伪随机数的网络攻击

有一个页面极其简洁的技术geek网站叫Hacker News,看名字就可以知道,这里活跃的都是一帮子快乐的程序员。其中一个快乐的程序员为了证明Hacker News在用户鉴权部分有一个致命的问题,在网站负责人的许可下,对网站进行了一次攻击,并且成功的获取了大量用户信息。

简单说一下他到底做了什么。

当你登录网站的时候,通常会被分配一个唯一的ID,作为本次session,即你本次登录行为的唯一标示。这个ID必须是你独有的,并且不能被其他人猜到,因为网站往往会使用这个ID对你的信息进行操作,如果被他人获取,别人就可以假扮是你,发出一些让网站误以为是你发出的请求,导致严重的后果。

在Hacker News网站上,这个ID是一串随机的字符串,例如HI4UKN3K51DS&WNJKSY*HJF,每个登录用户的字符串都不一样。网站内部使用了一个伪随机数生成器来为每个用户生成这样的ID,其中有一个算法负责不断的生成这样看起来很随机的字符串。

就如我们上文提到的一样,任何伪随机数生成器,都总会从一个seed开始,而Hacker News网站的seed,正是我们之前提到过的时间戳,即当前时间以毫秒为单位的得到的一串数字。每次网站运行的时候,都会取当时的时间戳作为seed,在网站运行期间,以这个seed生成所有用户的访问ID。

于是,攻击者首先想办法让网站后台挂掉,然后估算出网站大约会在之后约一分钟的时间段内重启,由此,他获取了一个网站seed的范围,通过有限次(一分钟也就60000毫秒)的尝试,一旦找到真正的seed,就可以成功的预测之后所有用户的ID,从而假扮为那些用户,进行恶意操作。

对网络安全有兴趣的同学,可以在文末找到这次攻击的具体内容。由此可见,伪随机数有两个问题,一个是seed可能被人预测,而个是产生随机数的算法可能是脆弱而可预测。

无所不在的随机数

也许有同学会说,好吧,我知道这个网站真的很脆弱,但是我也不用它呀~很遗憾,随机数的使用已经处于我们生活中的方方面面了。

比如,一旦你上网,使用https链接访问页面时,一个HTTPS链接的建立就必然有以下步骤:

1. 浏览器(也就是你自己的手机)发送信息给后台服务器,告知服务器它希望使用哪个版本的SSL进行加密。

2. 后台服务器回复了类似的关于可以支持的SSL版本和它的SSL证书

3. 浏览器确认证书有效,网站不是一个伪劣网站,于是它产生了一个随机的pre-master secret,用来加密之后的连接

之后你的浏览器和网站的所有连接,都建立在这个pre-master secret,它必须是无法预测的,从而保证网络连接的安全。

不只是https访问,包括手机wifi连接时候的WPA2协议,其中也不可避免的涉及到随机数用来加密的过程,可见,随机数已经涉及我们生活的各方面~

有一家名为cloudflare的公司,为了得到真随机数,甚至在公司办公室放了一面墙的熔岩灯。熔岩灯里放着蜡和水,蜡的密度在液态的时候略低于水,而在固态的时候略高于水,熔岩灯的底部有加热装置,使得密度比水大的固态蜡一旦落到底部,就会因为升温液化,从而又变得密度略低于水,再次上浮,于是周而复始,灯里的颜色一直在变化。公司每毫秒拍摄一次这堵墙的照片,从而得到一张时时刻刻都不一样的图,作为随机数的产生器,来看看这华丽的办公室一景。

可见,程序员们为了能得到足够安全的随机数,已经想破脑子了,下次使用随机数的时候,务必三思哦~


Refs:

https://blog.cloudflare.com/why-randomness-matters/

https://news.ycombinator.com/item?id=639976

Schönes Wochenende!

我的2019周更计划已完成:27/52

[********............]

0 人点赞