generate - Will python SystemRandom/os.urandom siempre tendrá suficiente entropía para una buena criptografía
generate random token python (3)
Es posible que desee leer esto sobre por qué / dev / urandom es el camino a seguir:
Tengo un generador de contraseñas:
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))
De acuerdo con los documentos, SystemRandom usa os.urandom que usa / dev / urandom para arrojar bits de crito al azar. En Linux, puede obtener bits aleatorios de / dev / urandom o / dev / random, ambos usan cualquier entropía que el kernel pueda tener en sus manos. La cantidad de entropía disponible se puede verificar con tail / proc / sys / kernel / random / entropy_avail, esto devolverá un número como: 129. Cuanto mayor sea el número, más entropía está disponible. La diferencia entre / dev / urandom y / dev / random es que / dev / random solo escupirá bits si entropy_avail es lo suficientemente alto (como al menos 60) y / dev / urandom siempre escupirá bits. Los documentos dicen que / dev / urandom es bueno para crypto y solo tienes que usar / dev / random para ssl certs y similares.
Mi pregunta es: ¿será gen_pass bueno para crear contraseñas de grado criptográfico sólidas siempre? Si llamo a esta función lo más rápido posible, ¿dejaré de emitir crios fuertes en algún momento porque el grupo de entropía está agotado?
La pregunta también podría ser: ¿por qué / dev / urandom siempre produce fuertes crios a trozos y no le importa el entropy_avail?
Es posible que / dev / urandom esté diseñado de modo que su ancho de banda esté limitado por la cantidad de ciclos que puede adivinar que se correlacionarán con una cantidad de entropía, pero esto es una especulación y no puedo encontrar una respuesta.
También esta es mi primera pregunta de stackoverflow así que por favor critícame. Me preocupa haber dado muchos antecedentes cuando alguien que sabe la respuesta probablemente conoce el fondo.
Gracias
actualizar
Escribí un código para ver el grupo de entropía mientras se leía el /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)
Si ejecuta esto y también ejecuta:
while 1 > 0:
gen_pass()
Luego obtengo de manera confiable una gráfica que se ve así:
Hacer el gráfico mientras se ejecuta cat /dev/urandom
parece smiler y cat /dev/random
reduce a nada y se mantiene bajo muy rápidamente (esto también se lee como un byte cada 3 segundos aproximadamente)
actualizar
Si ejecuto la misma prueba pero con seis instancias de gen_pass (), obtengo esto:
Así que parece que algo está haciendo que tenga suficiente entropía. Debería medir la tasa de generación de contraseñas y asegurarme de que realmente se está bloqueando, porque si no es así, entonces podría estar ocurriendo algo sospechoso.
actualizar
Encontré esta cadena de email
Esto dice que urandom dejará de tirar de la entropía una vez que la agrupación solo tenga 128 bits. Esto es muy consistente con los resultados anteriores y significa que en esas pruebas a menudo produzco contraseñas no deseadas.
Mi suposición antes era que si entropy_avail era lo suficientemente alto (por ejemplo, por encima de 64 bits), entonces la salida de /dev/urnadom
era buena. Este no es el caso, parece que /dev/urandom
fue diseñado para dejar entropía adicional para /dev/random
en caso de que lo necesite.
Ahora necesito averiguar cuántos bits aleatorios verdaderos necesita una llamada de SystemRandom.
Hay una diferencia sutil entre la salida de /dev/random
y /dev/urandom
. Como se ha señalado, /dev/urandom
no bloquea. Esto se debe a que obtiene su salida de un generador de números pseudoaleatorios, derivado de los números aleatorios ''reales'' en /dev/random
.
La salida de /dev/urandom
casi siempre será lo suficientemente aleatoria: es un PRNG de alta calidad con una semilla aleatoria. Si realmente necesita una mejor fuente de datos aleatorios, podría considerar obtener un sistema con un generador de números aleatorios de hardware: mi netbook tiene un VIA C7, que puede generar una gran cantidad de datos aleatorios (obtengo un 99.9 kb / s fuera de / dev / random, 545kb / s fuera de / dev / urandom).
Además, si está generando contraseñas, puede que quiera ver pwgen
, ya que las contraseñas son pwgen
pronunciar :).
/dev/random/
se bloqueará en lectura si necesita más entropía. /dev/urandom/
no lo hará. Así que sí, si lo usas demasiado rápido, te quedarás sin entropía. Probablemente todavía sea bastante difícil de adivinar, por supuesto, pero si está realmente preocupado puede leer bytes de /dev/random/
lugar. Idealmente, con un ciclo de lectura sin bloqueo y un indicador de progreso para que pueda mover el mouse y generar entropía si es necesario.