我有一个密码生成器:
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之间的区别在于/ dev / random只会在entropy_avail足够高(至少60)时吐出位,而/ dev / urandom总是吐出位。文档说/ dev / urandom对加密有好处,你只需要使用/ dev / random来获得ssl证书等。
我的问题是gen_pass是否适合制作强大的加密级密码?如果我尽快调用此函数,我会在某个时刻停止获取强大的cryto位,因为熵池已经耗尽了吗?
问题也可能是为什么/ dev / urandom 总是产生强烈的cryto位和而不关心entropy_avail?
有可能设计/ dev / urandom使其带宽受到可以猜测与熵量相关的周期数的限制,但这是推测,我无法找到答案。< / p>
这也是我的第一个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()
然后我非常可靠地得到一个如下图:
在运行cat /dev/urandom
时制作图表看起来很微笑,而cat /dev/random
下降到空,并且保持很低的速度(这也只是每隔3秒读出一个字节)
更新
如果我运行相同的测试,但有六个gen_pass()实例,我得到这个:
所以看起来有些东西让我有足够的熵。我应该测量密码生成速率,并确保它实际上被限制,因为如果不是,那么可能会发生一些可疑的事情。
更新
我发现了email chain
这表示一旦池中只有128位,urandom将停止拉熵。这与上述结果非常一致,意味着在那些测试中我经常生成垃圾密码。
我之前的假设是,如果entropy_avail足够高(比如高于64位),那么/dev/urnadom
输出就是好的。情况并非如此/dev/urandom
似乎旨在为/dev/random
留出额外的熵,以防万一需要它。
现在我需要找出SystemRandom调用需要多少个真正的随机位。
答案 0 :(得分:7)
/dev/random
和/dev/urandom
的输出之间存在细微差别。正如已经指出的那样,/dev/urandom
不会阻止。这是因为它从伪随机数生成器获取其输出,从/dev/random
中的“实际”随机数播种。
/dev/urandom
的输出几乎总是足够随机 - 它是一个带有随机种子的高质量PRNG。如果你真的需要一个更好的随机数据源,你可以考虑使用一个带有硬件随机数生成器的系统 - 我的上网本中有一个VIA C7,它可以生成大量正确的随机数据(我得到了一致的99.9) kb / s出/ dev / random,545kb / s出/ dev / urandom)。
顺便说一句,如果您正在生成密码,那么您可能需要查看pwgen
- 它为您提供了可识别的密码:)。
答案 1 :(得分:2)
/dev/random/
会阻止读取。 /dev/urandom/
不会。所以,是的,如果你使用得太快,你的熵就会很低。当然,可能仍然很难猜测,但如果你真的担心,你可以从/dev/random/
读取字节。理想情况下,使用非阻塞读取循环和进度指示器,以便您可以移动鼠标并在需要时生成熵。
答案 2 :(得分:-1)
您可能想要了解为什么/ dev / urandom是要走的路: