¿Es seguro el siguiente generador de contraseñas?

2

uso el siguiente generador de contraseñas (python) y me gustaría preguntar si las contraseñas generadas (generalmente de 32 caracteres y más) son lo suficientemente aleatorias.

def pwgen(l=32):
    from random import Random
    rng = Random()

    a = "qwertzuiopasdfghjklyxcvbnm"
    n = "1234567890"
    r = "23456qwertasdfgzxcvbQWERTASDFGZXCVOB"
    l = "78901yuiophjklnmYUIPHJKLNM"

    all = a + n + r  + l

    pwl = 32
    try:
        pwl = int(l)
    except:
        pass    
    if pwl < 8  or pwl > 128:
        pwl = 32

    pw = []
    for j in range(pwl):
        pw.append(rng.choice(all))

    return("".join(pw))

la contraseña producida se ve de la siguiente manera:

cwVPBgYt5seoO97sg8fszNptAhnb60Jg
W3mkuLMH0HCiJ8L040pmMys8yvhncwI8
kro01d2Z2ft51WG8lmy9d5el50aZ7CUg
10QfutP1fvKdR8oVhdTt0xR0r5k7w7Md
OxRjsqs2rCjyVbalvhuw3nrjTu9096XF
6jjvkIvyeoei3YIz84XAgdsDRjIGjyRu
2bjnHvubpv2z2DOF9fjFDfLtdnf4mL3T
UhbhNvwdSKOj14hmbca7t2UiwRaJNwrC
    
pregunta castorio 29.08.2013 - 22:34
fuente

2 respuestas

16
a = "qwertzuiopasdfghjklyxcvbnm"
n = "1234567890"
r = "23456qwertasdfgzxcvbQWERTASDFGZXCVOB"
l = "78901yuiophjklnmYUIPHJKLNM"

all = a + n + r  + l

¿Por qué esto es tan complicado? Al incluir algunos caracteres varias veces, es más probable que aparezcan en las contraseñas, lo que debilita la contraseña. Al hacer que la cadena de su contraseña sea tan complicada, es difícil determinar la seguridad de las contraseñas.

Para obtener una oportunidad uniforme de cualquier personaje, solo enumera todos ellos una vez. Además, puede simplificar dramáticamente esto utilizando el módulo string .

import string

all = string.ascii_letters + string.digits

Otro problema es que la documentación del módulo random dice que no se debe usar para la criptografía:

  

Python usa Mersenne Twister como generador de núcleo. Produce flotadores de precisión de 53 bits y tiene un período de 2 ** 19937-1. La implementación subyacente en C es rápida y segura para subprocesos. El Mersenne Twister es uno de los generadores de números aleatorios más ampliamente probados en existencia. Sin embargo, al ser completamente determinista, no es adecuado para todos los propósitos y es completamente inadecuado para propósitos criptográficos.

     

[...]

     

Advertencia: los generadores seudoaleatorios de este módulo no deben usarse por razones de seguridad. Use os.urandom () o SystemRandom si necesita un generador de números pseudoaleatorios seguro criptográficamente. **

Por lo tanto, use random.SystemRandom() en su lugar:

import random
import string

# Consider adding string.punctuation
possible_characters = string.ascii_letters + string.digits

def generate_password(length=32):
    rng = random.SystemRandom()
    return "".join([rng.choice(possible_characters) for i in range(length)])

Como sabemos exactamente cuántos caracteres posibles hay (62), y sabemos que deben distribuirse al azar, podemos decir con bastante confianza de que una contraseña generada por este esquema requerirá en promedio (62 ^ 32) / 2 (alrededor de 10 ^ 57) intenta adivinar.

Dicho esto, una contraseña de 32 caracteres es probablemente lo suficientemente segura, incluso si no es óptima al azar.

    
respondido por el Brendan Long 29.08.2013 - 22:56
fuente
5

La clase aleatoria de Python no es un generador de números aleatorios criptográficamente seguro, por lo que probablemente sea demasiado predecible para los atacantes. Además, está sembrado por una marca de tiempo (supongo que en milisegundos), lo que limita considerablemente el número de posibles flujos aleatorios y, por lo tanto, el número de contraseñas. Sería muy fácil forzar las contraseñas por cada milisegundo posible durante el cual podría haberse ejecutado el algoritmo, especialmente cuando el atacante puede estimar en qué momento ocurrió.

Editar: después de echar un vistazo más de cerca a la documentación de Python , parece que Python siembra el generador aleatorio con entropía de / dev / urandom (o su equivalente en Windows) en lugar de la hora del sistema, si está disponible. Así que no es tan inseguro como lo impliqué anteriormente. Sin embargo, todavía no debe confiar en el generador de números aleatorios predeterminado de Python para la generación de contraseñas. Recomiendo usar os.urandom o random.SystemRandom en su lugar, como lo indica el póster anterior.

    
respondido por el AardvarkSoup 29.08.2013 - 23:01
fuente

Lea otras preguntas en las etiquetas