2010-04-03 44 views
28

Buscando almacenar nombres de usuario y contraseñas en una base de datos, y me pregunto cuál es la forma más segura de hacerlo. Sé que tengo que usar una sal en alguna parte, pero no estoy seguro de cómo generarla de forma segura o cómo aplicarla para encriptar la contraseña. Algunos ejemplos de código Python serían muy apreciados. Gracias.El método más seguro de Python para almacenar y recuperar contraseñas de una base de datos

+0

un montón de información aquí: http://stackoverflow.com/questions/1183161/to-sha512-hash-a- password-in-mysql-database-by-python –

Respuesta

34

Almacenar la contraseña + sal como un hash y la sal. Eche un vistazo a cómo lo hace Django: basic docs y source. En el db almacenan <type of hash>$<salt>$<hash> en un solo campo char. También puede almacenar las tres partes en campos separados.

La función para establecer la contraseña:

def set_password(self, raw_password): 
    import random 
    algo = 'sha1' 
    salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5] 
    hsh = get_hexdigest(algo, salt, raw_password) 
    self.password = '%s$%s$%s' % (algo, salt, hsh) 

El get_hexdigest es sólo un envoltorio fino alrededor de algunos algoritmos de hash. Puedes usar hashlib para eso. Algo así como hashlib.sha1('%s%s' % (salt, hash)).hexdigest()

Y la función de comprobar la contraseña:

def check_password(raw_password, enc_password): 
    """ 
    Returns a boolean of whether the raw_password was correct. Handles 
    encryption formats behind the scenes. 
    """ 
    algo, salt, hsh = enc_password.split('$') 
    return hsh == get_hexdigest(algo, salt, raw_password) 
+0

¿Tiene un enlace al archivo de código apropiado? –

+0

Esto fue realmente útil. Muchas gracias. – ensnare

+0

@justin ethier: ya está. @ensnare: siéntase libre de marcarlo como aceptado ;-) –

3

Si usted tiene suficiente control sobre los dos puntos finales de la aplicación, la mejor manera absoluta está utilizando PAK-Z+.

(Editado: la versión original recomendada SRP pero PAK-Z + tiene una prueba de seguridad.)

0

aquí es una manera más sencilla (tomado de effbot), a condición de contraseñas con una longitud superior a 8 no será un problema *:

import crypt 

import random, string 

def getsalt(chars = string.letters + string.digits): 
    # generate a random 2-character 'salt' 
    return random.choice(chars) + random.choice(chars) 

para generar el contraseña:

crypt.crypt("password", getsalt()) 

*: Una contraseña con una longitud superior a 8 se elimina de la derecha hasta 8 caracteres de largo

+0

crypt tiene problemas para cifrar la contraseña de más de 8 caracteres Creo que – llazzaro

10

que respondieron esta aquí: https://stackoverflow.com/a/18488878/1661689, y lo mismo hizo @Koffie.

No sé cómo hacer suficiente hincapié en que la respuesta aceptada NO es segura. Es mejor que el texto sin formato, y mejor que un hash sin sal, pero sigue siendo extremadamente vulnerable al diccionario e incluso ataques de fuerza bruta. En su lugar, utilizan un KDF LENTO como bcrypt (o al menos PBKDF2 con 10.000 iteraciones)

+0

¿Está sugiriendo que el almacenamiento de contraseñas hashed correctamente salados es una práctica ** extremadamente vulnerable **? No puede usar un ataque de diccionario en hashes salados. – vroomfondel

+0

No. Estoy sugiriendo que una sola iteración de SHA-1, como sugiere el código anterior, no está "correctamente salada y picada". Usted * puede * usar un ataque de diccionario en hashes salados, y cuanto más rápido sea el hash, más rápido se podrá probar cada pw. ¿Preferiría que transcurriera un día o 64,000 días para que el ataque tuviera éxito? El hash SHA-x es * muy * rápido en hardware personalizado (ASIC). https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet#Impose_infeasible_verification_on_attacker http://stackoverflow.com/questions/13545677/python-passlib-what-is-the-best-value-for-rounds –

+1

@rz dice "Eche un vistazo a cómo lo hace Django" y luego muestra un código que es completamente diferente. Django * does * lo hace correctamente: https://github.com/django/django/blob/master/django/contrib/auth/hashers.py#L216 –

Cuestiones relacionadas