Python的SystemRandom / os.urandom总是有足够的熵来encryption

我有一个密码生成器

import random, string def gen_pass(): foo = random.SystemRandom() length = 64 chars = string.letters + string.digits return ''.join(foo.choice(chars) for _ in xrange(length)) 

根据文档,SystemRandom使用os.urandom使用/ dev / urandom丢弃随机cryto位。 在Linux中,你可以从/ dev / urandom或者/ dev / random中得到随机数,它们都使用内核可以得到的任何熵。 可以使用tail / proc / sys / kernel / random / entropy_avail来检查可用的熵的数量,这将返回一个数字,如:129。熵越高,可用的熵越多。 / dev / urandom和/ dev / random之间的区别在于,如果entropy_avail足够高(至less60),/ dev / random将只会吐出位,而/ dev / urandom将始终吐出位。 这个文档说/ dev / urandom对encryption来说是很好的,你只需要使用/ dev / random来获得ssl证书等等。

我的问题是,gen_pass会不会很好地生成强密码级密码? 如果我尽可能快地调用这个函数,那么在某个点上我将不再获得强大的cryto比特,因为熵池已经耗尽了。

这个问题也可能是为什么/ dev / urandom 总是产生强大的cryto而不关心entropy_avail?

有可能/ dev / urandom的devise是为了让它的带宽被你猜测的周期数与熵数相关,但这是猜测,我找不到答案。

另外这是我的第一个stackoverflow问题,所以请批评我。 我担心,当知道答案的人可能知道背景时,我给了很多背景。

谢谢

更新

我写了一些代码来查看熵池,而正在读取/dev/urandom

 import subprocess import time from pygooglechart import Chart from pygooglechart import SimpleLineChart from pygooglechart import Axis def check_entropy(): arg = ['cat', '/proc/sys/kernel/random/entropy_avail'] ps = subprocess.Popen(arg,stdout=subprocess.PIPE) return int(ps.communicate()[0]) def run(number_of_tests,resolution,entropy = []): i = 0 while i < number_of_tests: time.sleep(resolution) entropy += [check_entropy()] i += 1 graph(entropy,int(number_of_tests*resolution)) def graph(entropy,rng): max_y = 200 chart = SimpleLineChart(600, 375, y_range=[0, max_y]) chart.add_data(entropy) chart.set_colours(['0000FF']) left_axis = range(0, max_y + 1, 32) left_axis[0] = 'entropy' chart.set_axis_labels(Axis.LEFT, left_axis) chart.set_axis_labels(Axis.BOTTOM,['time in second']+get_x_axis(rng)) chart.download('line-stripes.png') def get_x_axis(rng): global modnum if len(filter(lambda x:x%modnum == 0,range(rng + 1)[1:])) > 10: modnum += 1 return get_x_axis(rng) return filter(lambda x:x%modnum == 0,range(rng + 1)[1:]) modnum = 1 run(500,.1) 

如果运行这个,也运行:

 while 1 > 0: gen_pass() 

然后我相当可靠地得到一个如下图所示的graphics: 在这里输入图像说明

在运行cat /dev/urandom同时创buildgraphics看起来像smiler和cat /dev/random非常快的,并且保持低速(这也只是每隔3秒左右读一个字节)

更新

如果我运行相同的testing,但有六个gen_pass()实例,我得到这个: 在这里输入图像说明

所以看起来好像是有足够的熵。 我应该测量密码的生成速度,并确保它实际上被封顶,因为如果不是,那么可能会发生一些可疑的事情。

更新

我发现这个电子邮件链

这就是说,一旦游泳池只有128位,游戏就会停止提取熵。 这与上述结果非常一致,意味着在那些testing中我经常会生成垃圾密码。

我之前的假设是,如果entropy_avail足够高(比如高于64位),那么/dev/urnadom输出是好的。 不是这样的, /dev/urandom被devise为在需要的时候为/dev/random留下额外的熵。

现在我需要找出一个SystemRandom调用需要多less个真正的随机位。

Solutions Collecting From Web of "Python的SystemRandom / os.urandom总是有足够的熵来encryption"

/dev/random/dev/urandom的输出之间有细微的差别。 正如已经指出的那样, /dev/urandom不会阻塞。 这是因为它从一个伪随机数发生器获得输出,从/dev/random的“真正”随机数开始播种。

/dev/urandom的输出将几乎总是足够随机的 – 这是一个随机种子的高品质PRNG。 如果你真的需要一个更好的随机数据源,你可以考虑用一个硬件随机数发生器获得一个系统 – 我的上网本中有一个VIA C7,它可以产生相当多的随机数据(我得到一个一致的99.9 kb / s out / dev / random,545kb / s out of / dev / urandom)。

另外,如果你正在生成密码,那么你可能要看看pwgen – 它为你提供了很好的口令:)。

如果需要更多的信息, /dev/random/会阻止读取。 /dev/urandom/不会。 所以是的,如果你使用得太快,熵就会降低。 当然,可能还是很难猜到,但是如果你真的担心,可以从/dev/random/读取字节。 理想情况下,使用非阻塞读取循环和进度指示器,以便您可以移动鼠标并根据需要生成熵。

您可能想要阅读关于/ dev / urandom为何如此的解释:

http://www.2uo.de/myths-about-urandom/