Czy python SystemRandom / os.urandom zawsze ma wystarczająco dużo entropii na dobrą krypto
Mam generator haseł:
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))
Zgodnie z dokumentami, SystemRandom używa systemu operacyjnego.urandom, który używa /dev/urandom do wyrzucania losowych bitów cryto. W Linuksie można uzyskać losowe bity z /dev /urandom lub/dev / random, oba używają dowolnej entropii, którą jądro może dostać w swoje ręce. Ilość dostępnej entropii można sprawdzić za pomocą tail / proc / sys/kernel/random / entropy_avail, zwróci to liczbę taką jak: 129. Im wyższa liczba, tym więcej entropii jest dostępnych. Różnica pomiędzy /dev /urandom i/dev / random jest to, że / dev / random wypluwa bity tylko wtedy, gdy entropy_avail jest wystarczająco wysoka (jak co najmniej 60), a / dev / urandom zawsze wypluwa bity. Dokumenty mówią, że /dev/urandom jest dobre dla crypto i musisz używać /dev / random tylko dla Cert ssl i tym podobnych.
Moje pytanie brzmi, czy gen_pass będzie zawsze dobry do tworzenia silnych haseł klasy kryptograficznej? Jeśli wywołam tę funkcję tak szybko, jak to możliwe, przestanę w pewnym momencie uzyskiwać silne bity cryto, ponieważ Pula entropii jest wyczerpana?
Pytanie może również brzmieć: dlaczego /dev/urandom zawsze wytwarza silne bity krytyczne i nie dba o entropy_avail?
Jest możliwe, że /dev/urandom jest tak zaprojektowany, że jego przepustowość jest ograniczona liczbą cykli, które można się domyślić, będzie skorelowana z ilością entropii, ale to spekulacje i nie mogę znaleźć odpowiedzi.
To też moje pierwsze pytanie o stackoverflow, więc proszę mnie skrytykować. Jestem zaniepokojony, że dałem dużo tła, gdy ktoś, kto zna odpowiedź prawdopodobnie zna tło.
Dzięki
Update
Napisałem kod, aby spojrzeć na pulę entropii podczas czytania /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)
If run this and also run:
while 1 > 0:
gen_pass()
Wtedy całkiem wiarygodnie dostaję wykres, który wygląda tak:
Tworzenie wykresu podczas biegu cat /dev/urandom
wygląda na uśmiechnięte i cat /dev/random
spada do zera i pozostaje nisko bardzo szybko (to również odczytuje się jak bajt co około 3 sekundy)
Update
Jeśli wykonam ten sam test, ale z sześcioma instancjami gen_pass(), dostaję to:
Wygląda na to, że coś sprawia, że mam wystarczająco dużo entropii. Powinienem zmierzyć szybkość generowania hasła i upewnić się, że jest ono faktycznie ograniczone, ponieważ jeśli nie jest, to może się dziać coś podejrzanego.Update
Znalazłem to łańcuch e-mail
To mówi, że urandom przestanie ciągnąć entropię, gdy pula będzie miała tylko 128 bitów. Jest to bardzo zgodne z powyższymi wynikami i oznacza, że w tych testach często wytwarzam śmieciowe hasła.
Moje wcześniejsze założenie było takie, że jeśli entropy_avail była wystarczająco wysoka (powiedzmy powyżej 64 bitów), to wyjście /dev/urnadom
było dobre. Nie jest tak, że wydaje się, że /dev/urandom
został zaprojektowany, aby pozostawić dodatkową entropię dla /dev/random
w razie potrzeby.
Teraz potrzebuję aby dowiedzieć się, ile prawdziwych losowych bitów potrzebuje połączenie SystemRandom.
3 answers
Istnieje subtelna różnica między wyjściem /dev/random
i /dev/urandom
. Jak już wspomniano, /dev/urandom
nie blokuje. Wynika to z faktu, że generuje on pseudolosowy generator liczb, z "rzeczywistych" liczb losowych w /dev/random
.
Wyjście {[1] } będzie prawie zawsze wystarczająco losowe -- to wysokiej jakości PRNG z losowym nasionem. Jeśli naprawdę potrzebujesz lepszego źródła losowych danych, możesz rozważyć zakup systemu ze sprzętowym generatorem liczb losowych-mój netbook ma w sobie VIA C7, który może generować sporo właściwie losowych danych (ja dostaję spójne 99.9 kb/s z /dev/random, 545kb/s z /dev/urandom).
Na marginesie, jeśli generujesz hasła, to może warto przyjrzeć się pwgen
-- to sprawia, że ładne hasła wymawialne dla Ciebie :).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-31 09:59:43
/dev/random/
zablokuje odczyt, jeśli potrzebuje więcej entropii. Więc tak, jeśli użyjesz go zbyt szybko, zabraknie Ci entropii. Prawdopodobnie nadal trudno się domyślić, ale jeśli naprawdę się martwisz, możesz czytać bajty z /dev/random/
. Najlepiej, z nieblokującą pętlą odczytu i wskaźnikiem postępu, dzięki czemu można poruszać myszką i generować entropię w razie potrzeby.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-29 23:31:18
Możesz przeczytać to o tym, dlaczego /dev/urandom jest drogą do zrobienia:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-16 15:15:25