首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python SystemRandom / os.urandom总是有足够的熵来进行良好的加密吗?

python SystemRandom / os.urandom总是有足够的熵来进行良好的加密吗?
EN

Stack Overflow用户
提问于 2011-03-29 23:25:32
回答 3查看 7.4K关注 0票数 23

我有一个密码生成器:

代码语言:javascript
复制
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来丢弃随机密码位。在Linux中,您可以从/dev/urandom/dev/random获得随机位,它们都使用内核可以获得的任何熵。可用的熵量可以用tail /proc/sys/kernel/random/entropy_avail检查,这将返回一个类似于: 129的数字。数字越高,熵就越大。/dev/urandom/dev/random的区别在于,只有当entropy_avail足够高(至少60)时,/dev/random才会吐出比特,而/dev/urandom总是会吐出比特。文档说/dev/urandom对密码很好,您只需在ssl证书等方面使用/dev/random即可。

我的问题是,gen_pass是否总是适合做强加密等级的密码?如果我尽快调用这个函数,我会因为熵池耗尽而在某个点停止获得强密码位吗?

问题还可能是为什么/dev/urandom总是产生强大的密码位而不关心entropy_avail

/dev/urandom的设计可能是为了使它的带宽被你可以猜到的与熵相关的循环数所限制,但这是推测,我找不到答案。

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

谢谢

更新

在阅读/dev/urandom时,我编写了一些代码来查看熵池:

代码语言:javascript
复制
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)

如果运行此命令并同时运行:

代码语言:javascript
复制
while 1 > 0:
    gen_pass()

然后我很可靠地得到了这样的图形:

运行cat /dev/urandom时使图形看起来更光滑,cat /dev/random下降到零,很快就会保持低水平(这也只是每3秒读一次字节)。

更新

如果我运行相同的测试,但使用gen_pass()的六个实例,则得到以下结果:

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

更新

我找到了这个电子邮件链

这意味着,一旦池中只有128位,urandom将停止提取熵。这与上述结果非常一致,这意味着在这些测试中,我经常会生成垃圾密码。

我之前的假设是,如果entropy_avail足够高(比如64位以上),那么/dev/urandom输出是好的。事实并非如此,/dev/urandom似乎是为了在需要的情况下为/dev/random留出额外的熵。

现在,我需要知道一个SystemRandom调用需要多少真正的随机位。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-31 09:59:43

/dev/random/dev/urandom的输出之间有一个细微的差别。正如已经指出的,/dev/urandom不会阻止。这是因为它的输出来自一个伪随机数生成器,它是从/dev/random中的“实数”随机数中播种的。

/dev/urandom的输出几乎总是随机的--这是一种具有随机种子的高质量PRNG。如果你真的需要一个更好的随机数据来源,你可以考虑得到一个带有硬件随机数生成器的系统--我的上网本中有一个通过C7,它可以产生相当多的随机数据(我从/dev/random中得到了一致的99.9kb/s,从/dev/urandom中得到了545 in /s)。

另外,如果您正在生成密码,那么您可能需要查看pwgen --它为您提供了很好的可发音密码:)。

票数 7
EN

Stack Overflow用户

发布于 2011-03-29 23:31:18

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

票数 2
EN

Stack Overflow用户

发布于 2017-01-16 15:15:25

您可能需要阅读以下关于为什么/dev/urandom是前进道路的文章:

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

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5480131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档