问题描述
我有一个密码生成器:
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 是否总是有足够的熵来进行良好的加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!