Будет ли Python SystemRandom / os.urandom всегда иметь достаточно энтропии для хорошей криптографии - PullRequest
21 голосов
/ 30 марта 2011

У меня есть генератор паролей:

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()

Тогда я довольно надежно получаю график, который выглядит следующим образом: enter image description here

Создание графика во время работы cat /dev/urandomвыглядит улыбчиво и cat /dev/random падает до нуля и остается очень низким (это также считывает только как байт каждые 3 секунды или около того)

update

ЕслиЯ запускаю тот же тест, но с шестью экземплярами gen_pass () я получаю это: enter image description here

Так что, похоже, что-то делает так, что у меня достаточно энтропии.Я должен измерить частоту генерации пароля и убедиться, что он действительно ограничен, потому что если это не так, то может происходить что-то подозрительное.

обновление

Я нашел эту цепочку писем

Это говорит о том, что urandom перестанет тянуть энтропию, как только в пуле будет 128биты в нем.Это очень согласуется с приведенными выше результатами и означает, что в этих тестах я часто создаю нежелательные пароли.

Раньше я предполагал, что если entropy_avail был достаточно высоким (скажем, выше 64 бит), то вывод /dev/urnadom был бы хорошим.Это не тот случай, кажется, что /dev/urandom был разработан, чтобы оставить дополнительную энтропию для /dev/random в случае, если это необходимо.

Теперь мне нужно выяснить, сколько истинных случайных битов необходимо для вызова SystemRandom.

Ответы [ 3 ]

7 голосов
/ 31 марта 2011

Существует небольшая разница между выходными значениями /dev/random и /dev/urandom.Как было указано, /dev/urandom не блокируется.Это потому, что он получает выходные данные от генератора псевдослучайных чисел, отобранного из «реальных» случайных чисел в /dev/random.

Выход /dev/urandom почти всегда будет достаточно случайным - это высокийPRNG со случайным семенемЕсли вам действительно нужен лучший источник случайных данных, вы можете подумать о том, чтобы получить систему с аппаратным генератором случайных чисел - в моем нетбуке есть VIA C7, который может генерировать довольно много случайных данных (я получаю непротиворечивые 99,9).КБ / с из / dev / random, 545 КБ / с из /dev/urandom).

Кроме того, если вы генерируете пароли, вы можете посмотреть на pwgen - это делает хорошие произносимые пароли для вас:).

2 голосов
/ 30 марта 2011

/dev/random/ будет блокироваться при чтении, если ему нужно больше энтропии. /dev/urandom/ не будет. Так что да, если вы используете его слишком быстро, у вас не останется энтропии. Конечно, все еще трудно догадаться, но если вы действительно обеспокоены, вы можете вместо этого читать байты из /dev/random/. В идеале, с неблокирующим циклом чтения и индикатором прогресса, чтобы вы могли перемещать мышь и генерировать энтропию при необходимости.

0 голосов
/ 16 января 2017

Возможно, вы захотите прочитать о том, почему / dev / urandom - это путь:

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

...