python SystemRandom/os.urandom 是否总是有足够的熵来进行良好的加密 [英] Will python SystemRandom / os.urandom always have enough entropy for good crypto

查看:19
本文介绍了python SystemRandom/os.urandom 是否总是有足够的熵来进行良好的加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个密码生成器:

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 对加密有好处,您只需将/dev/random 用于 ssl 证书等.

According to the docs, SystemRandom uses os.urandom which uses /dev/urandom to throw out random cryto bits. In Linux you can get random bits from /dev/urandom or /dev/random, they both use whatever entropy the kernel can get its hands on. The amount of entropy available can be checked with tail /proc/sys/kernel/random/entropy_avail, this will return a number like: 129. The higher the number more entropy is available. The difference between /dev/urandom and /dev/random is that /dev/random will only spit out bits if entropy_avail is high enough (like at least 60) and /dev/urandom will always spit out bits. The docs say that /dev/urandom is good for crypto and you only have to use /dev/random for ssl certs and the like.

我的问题是 gen_pass 是否总是适合制作强加密级密码?如果我尽快调用此函数,是否会因为熵池已耗尽而在某个时候停止获取强加密位?

My question is will gen_pass be good for making strong crypto grade passwords always? If I call this function as quickly as possible will I stop getting strong cryto bits at some point because the entropy pool is depleted?

问题也可能是为什么/dev/urandom 总是 产生强加密位 不关心 entropy_avail?

The question could also be why does /dev/urandom always produce strong cryto bits and not care about the entropy_avail?

可能/dev/urandom 的设计使其带宽受限于您可以猜测的与熵量相关的周期数,但这是推测,我找不到答案.

It is possible that /dev/urandom is designed so that its bandwidth is capped by the number of cycles you can guess will be correlated with an amount of entropy, but this is speculation and I can't find an answer.

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

Also this is my first stackoverflow question so please critique me. I am concerned that I gave to much background when someone who knows the answer probably knows the background.

谢谢

更新

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

I wrote some code to look at the entropy pool while the /dev/urandom was being read from:

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)

如果运行这个并同时运行:

If run this and also run:

while 1 > 0:
    gen_pass()

然后我很可靠地得到一个如下所示的图表:

Then I pretty reliablly get a graph that looks like this:

在运行 cat/dev/urandom 时制作图表看起来更微笑,而 cat/dev/random 会很快下降并保持在低位(这也只会读出像每 3 秒左右一个字节)

Making the graph while running cat /dev/urandom looks smiler and cat /dev/random drops off to nothing and stays low very quickly (this also only reads out like a byte every 3 seconds or so)

更新

如果我运行相同的测试但有六个 gen_pass() 实例,我会得到:

If I run the same test but with six instances of gen_pass(), I get this:

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

So it looks like something is making it be the case that I have enough entropy. I should measure the password generation rate and make sure that it is actually being capped, because if it is not then something fishy may be going on.

更新

我找到了这个电子邮件链

这表示一旦池中只有 128 位,urandom 将停止拉熵.这与上述结果非常一致,这意味着在这些测试中我经常产生垃圾密码.

This says that urandom will stop pulling entropy once the pool only has 128 bits in it. This is very consistent with the above results and means that in those tests I am producing junk passwords often.

我之前的假设是,如果 entropy_avail 足够高(比如高于 64 位),那么 /dev/urnadom 输出就很好.情况并非如此,似乎 /dev/urandom 旨在为 /dev/random 留下额外的熵,以备不时之需.

My assumption before was that if the entropy_avail was high enough (say above 64 bits) then /dev/urnadom output was good. This is not the case it seems that /dev/urandom was designed to leave extra entropy for /dev/random in case it needs it.

现在我需要找出 SystemRandom 调用需要多少真正的随机位.

Now I need to find out how many true random bits a SystemRandom call needs.

推荐答案

/dev/random/dev/urandom 的输出有细微差别.正如已经指出的那样, /dev/urandom 不会阻塞.这是因为它的输出来自一个伪随机数生成器,该生成器从 /dev/random 中的真实"随机数中播种.

There's a subtle difference between the output of /dev/random and /dev/urandom. As has been pointed out, /dev/urandom doesn't block. That's because it gets its output from a pseudo-random number generator, seeded from the 'real' random numbers in /dev/random.

/dev/urandom 的输出几乎总是足够随机的——它是一个带有随机种子的高质量 PRNG.如果你真的需要更好的随机数据源,你可以考虑买一个带有硬件随机数生成器的系统——我的上网本有一个威盛 C7,它可以生成相当多的正确随机数据(我得到一个一致的 99.9/dev/random 中的 kb/s,/dev/urandom 中的 545kb/s).

The output of /dev/urandom will almost always be sufficiently random -- it's a high-quality PRNG with a random seed. If you really need a better source of random data, you could consider getting a system with a hardware random number generator -- my netbook has a VIA C7 in it, which can generate quite a lot of properly random data (I get a consistent 99.9kb/s out of /dev/random, 545kb/s out of /dev/urandom).

顺便说一句,如果您要生成密码,那么您可能需要查看 pwgen -- 它为你提供了很好的发音密码:).

As an aside, if you're generating passwords then you might want to look at pwgen -- it makes nice pronounceable passwords for you :).

这篇关于python SystemRandom/os.urandom 是否总是有足够的熵来进行良好的加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆