2011-03-29 5 views
20

Ho un generatore di password:Will python SystemRandom/os.urandom avere sempre abbastanza entropia per una buona crypto

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

Secondo la documentazione, SystemRandom utilizza os.urandom che utilizza/dev/urandom di buttare fuori casuale cripta. In Linux puoi ottenere bit casuali da/dev/urandom o/dev/random, entrambi usano qualunque entropia su cui il kernel può mettere le mani. La quantità di entropia disponibile può essere controllata con tail/proc/sys/kernel/random/entropy_avail, questo restituirà un numero come: 129. Più è alto il numero di entropia più disponibile. La differenza tra/dev/urandom e/dev/random è che/dev/random sputerà solo bit se entropy_avail è abbastanza alto (come almeno 60) e/dev/urandom sputerà sempre bit. I documenti dicono che/dev/urandom è buono per crypto e devi solo usare/dev/random per ssl certs e simili.

La mia domanda è gen_pass è buono per creare password di crittografia forte sempre? Se chiamo questa funzione il più rapidamente possibile, smetterò di ottenere forti cryto bit ad un certo punto perché il pool di entropia è esaurito?

La questione potrebbe anche essere il motivo per cui non/dev/urandom sempre produrre forti bit Cryto e si cura del entropy_avail?

È possibile che/dev/urandom sia progettato in modo che la sua larghezza di banda sia limitata dal numero di cicli che è possibile indovinare che saranno correlati con una quantità di entropia, ma questa è una speculazione e non riesco a trovare una risposta.

Anche questa è la mia prima domanda StackOverflow quindi vi prego di criticare. Sono preoccupato del fatto che ho dato molto background quando qualcuno che conosce la risposta probabilmente conosce lo sfondo.

Grazie

aggiornamento

Ho scritto un codice a guardare il pozzo d'entropia mentre il /dev/urandom si leggeva da:

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) 

Se eseguire questo e anche eseguire:

while 1 > 0: 
    gen_pass() 

Poi ho abbastanza reliablly ottenere un grafico che assomiglia a questo: enter image description here

Fare il grafico durante l'esecuzione cat /dev/urandom sembra Smiler e cat /dev/random cade a nulla e rimane basso molto rapidamente (anche questo si legge solo come un byte ogni 3 secondi o giù di lì)

aggiornamento

Se corro lo stesso test, ma con sei casi di gen_pass(), ottengo questo: enter image description here

Quindi sembra che stia accadendo che ho abbastanza entropia. Dovrei misurare il tasso di generazione della password e assicurarmi che sia effettivamente limitato, perché se non lo è, può succedere qualcosa di sospetto.

aggiornamento

ho trovato questo email chain

Questo dice che urandom smetterà tirando entropia volta la piscina ha solo 128 bit in esso. Questo è molto coerente con i risultati di cui sopra e significa che in quei test sto producendo spesso le password spazzatura.

La mia ipotesi precedente era che se entropy_avail era sufficientemente alto (diciamo sopra 64 bit) l'output /dev/urnadom era buono. Questo non è il caso sembra che /dev/urandom è stato progettato per lasciare entropia extra per /dev/random nel caso in cui ne ha bisogno.

Ora ho bisogno di scoprire quanti bit casuali veri richiedono una chiamata SystemRandom.

+0

Naturalmente è possibile - è possibile disegnare una quantità indefinita di informazioni da/dev/urandom, e si non hanno una quantità indefinita di entropia. –

+0

Come ho detto sopra, penso che potresti progettare è così che non è possibile, ma non ho motivo di crederci. Ho bisogno di fare più ricerche. – Chris

+0

@Chris Come? L'entropia deve venire da qualche parte - non puoi semplicemente incantarla. Se tu potessi, le nostre vite sarebbero molto più facili. –

risposta

7

C'è una sottile differenza tra l'output di /dev/random e /dev/urandom. Come è stato sottolineato, /dev/urandom non blocca. Questo perché riceve l'output da un generatore di numeri pseudo-casuali, seminato dai numeri casuali "reali" in /dev/random.

L'output di /dev/urandom sarà quasi sempre casuale: è un PRNG di alta qualità con un seme casuale. Se hai davvero bisogno di una fonte migliore di dati casuali, potresti considerare di ottenere un sistema con un generatore di numeri casuali dell'hardware - il mio netbook ha un VIA C7 in esso, che può generare un sacco di dati casuali (ottengo un 99,9 coerente kb/s su/dev/random, 545kb/s su/dev/urandom).

Per inciso, se stai generando password, ti consigliamo di dare un'occhiata a pwgen - per te è una buona password pronunciabile :).

+0

Rite, penso di aver dimostrato a me stesso che questo funzionerà bene, ma che l'hardware sicuro è la strada da percorrere. Ora ho solo bisogno di capire come collegare il mio contatore geiger fino a una porta seriale ... – Chris

+0

[Questa risposta non è corretta] (http://security.stackexchange.com/questions/3936/is-a-rand-from -dev-urandom-secure-for-a-login-key), sia 'random' che' urandom' recuperano i loro valori da un PRNG. Blocchi 'casuali' quando c'è troppo poca entropia nel pool di entropia, tuttavia l'entropia viene salvata e ricaricata quando si riavvia la macchina, quindi non si esaurisce praticamente mai. L'unica volta in cui 'urandom' potrebbe dare "valori di PRNG a bassa entropia" è se hai appena installato la tua macchina e immediatamente leggi da/dev/urandom'. –

2

/dev/random/ si blocca in lettura se ha bisogno di più entropia. /dev/urandom/ no. Quindi sì, se lo usi troppo in fretta, sarai a corto di entropia. Probabilmente è ancora abbastanza difficile da indovinare, ovviamente, ma se sei davvero preoccupato puoi leggere i byte da /dev/random/ invece. Idealmente, con un ciclo di lettura non bloccante e un indicatore di avanzamento in modo da poter spostare il mouse e generare entropia, se necessario.

+0

'/ dev/random' sembra effettivamente fornire i bit direttamente dal pool di entropia, e dagli esperimenti l'entropia viene esaurita molto rapidamente. Se è possibile che '/ dev/urandom' fallisca mi piacerebbe sapere di più su come funziona e se puoi prevenirlo. Se esegui 'cat/dev/urandom' e fai schifo allo IO standard e controlli periodicamente anche entropy_avail, non sembra che ci sia mai un problema con entropy_avail. Mi chiedo se il kernel stia usando il processo di stampa '/ dev/urandom /' per fare più entropia, mi chiedo anche se sia accettabile. – Chris

+0

Il mio ricordo è che lo prendono dallo stesso posto, ma 'random' tiene traccia di quanta entropia è disponibile e blocca quando ha bisogno di più. Suppongo che 'urandom' aggiorni anche lo stato di entropia, dato che qualcuno potrebbe disegnare su' random' in qualsiasi momento. Come stai controllando entropy_avail? Ad ogni modo, direi che usare 'urandom' e passarlo attraverso una funzione di hash sicura sarebbe abbastanza sicuro per quasi tutte le applicazioni. –

Problemi correlati