У меня есть генератор паролей:
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 заключается в том, что / dev / random будет выплевывать биты только в том случае, если entropy_avail достаточно высоко (как минимум 60), а / dev / urandom всегда будет выплевывать биты.В документах говорится, что / dev / urandom хорош для криптографии, и вы должны использовать / dev / random только для ssl-сертификатов и тому подобного.
Мой вопрос: будет ли gen_pass хорош для создания надежных паролей крипто-класса?Если я вызову эту функцию как можно быстрее, я перестану получать сильные крипто-биты в какой-то момент, потому что пул энтропии исчерпан?
Может также возникнуть вопрос, почему / dev / urandom всегда генерировать сильные криптобиты и , не заботясь о entropy_avail?
Возможно, что / dev / urandom разработан так, что его пропускная способность ограничена числом циклов, которое, как вы можете догадаться, будет коррелированос некоторой энтропией, но это предположение, и я не могу найти ответ.
Также это мой первый вопрос о переполнении стека, поэтому, пожалуйста, критикуйте меня.Я обеспокоен, что я дал много фона, когда кто-то, кто знает ответ, вероятно, знает фон.
Спасибо
обновление
Я написал код для просмотра пула энтропии, пока /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 секунды или около того)
update
ЕслиЯ запускаю тот же тест, но с шестью экземплярами gen_pass () я получаю это:
Так что, похоже, что-то делает так, что у меня достаточно энтропии.Я должен измерить частоту генерации пароля и убедиться, что он действительно ограничен, потому что если это не так, то может происходить что-то подозрительное.
обновление
Я нашел эту цепочку писем
Это говорит о том, что urandom перестанет тянуть энтропию, как только в пуле будет 128биты в нем.Это очень согласуется с приведенными выше результатами и означает, что в этих тестах я часто создаю нежелательные пароли.
Раньше я предполагал, что если entropy_avail был достаточно высоким (скажем, выше 64 бит), то вывод /dev/urnadom
был бы хорошим.Это не тот случай, кажется, что /dev/urandom
был разработан, чтобы оставить дополнительную энтропию для /dev/random
в случае, если это необходимо.
Теперь мне нужно выяснить, сколько истинных случайных битов необходимо для вызова SystemRandom.