Pseudo Random Number Generation Lab
本次实验将会学习:
伪随机数生成
生成随机数时的错误
生成加密密钥
/dev/random和/dev/urandom设备文件
Task 1错误的方式生成加密密钥
伪随机数的生成事实上是可以预测的
比如下面的代码使用当前时间用作伪随机数生成的种子
Time()会返回从1970-01-01 00:00:00开始以来的秒数
编译后运行几次可以看到
将srand那一句注释后
从结果可以看到,注释了srand后,光用rand是非常危险的
Task2 猜测key
根据描述场景,暴力破解即可
Task3 测量内核的熵
单单使用软件是很难生成真随机数的。大多数系统会从物理世界获得随机性,linux从以下获得随机性:
第一个是用两次按键之前的计时,第二个是用鼠标的移动以及中断的计时,第三个是使用中断计时收集随机数(当然,也不是所有中断都是好的随机数,比如,计时器中断就不是好选择,因为这是可预测的,而磁盘中断是一个更好的选择),最后一个是测量块设备请求的完成时间。
随机性用熵来衡量,这和信息论中的概念不一样,在这里仅仅指系统当前拥有多少比特的随机数。比如可以用下列命令找到目前内核的熵
也可以使用watch观察熵的改变
watch -n .1 cat /proc/sys/kernel/random/entropy_avail
当运行这条命令时,做些动作比如移动鼠标,阅读文档等,会发现熵值会有显著的变化
Task4 从/dev/random获得伪随机数
linux把从物理资源中获得的随机数存在随机数池random pool里,然后使用两个设备将随机性转为伪随机数,他们分别是/dev/random和/dev/urandom。
/dev/random是块设备,每次该设备给出一个随机数时,randomness pool的熵值就会降低。当熵值达到0时,/dev/random就阻塞的,直到其重新获得足够的随机性。
我们来观察/dev/random
我们使用cat命令从其中读出随机数,使用管道命令将其输出
配合前面的watch命令可以看到,随着cat的输出,watch看到的值一直在减小
Task5 从/dev/urandom获取随机数
linux也可以通过/dev/urandom从random pool中获得随机数,不过其不会被阻塞。
当熵不足时,/dev/random会停止,而/dev/urandom会继续生成新的随机数。将pool里的数据视为种子,我们事实上可以生成任意多的伪随机数。
同样使用cat来观察其行为
可以看到它生产的速度快得多,而且与熵无关
那么我们来看看其生成的随机数的质量如何。
我们先用/dev/urandom生成1m的数据并将其保存到文件,然后使用ent进行测试
可以看到这个熵值是非常小的,说明生成的随机数的质量不高
理论上将/dev/random更安全,但是实际上并没有太大区别,而且/dev/random可能导致dos,因此还是推荐使用/dev/urandom。
在编程的时候可以直接从设备读出来