password funcion python authentication hash passwords salt

funcion - Sal y hash una contraseña en python



python hash password (6)

Se supone que este código debe hash una contraseña con un salt. La contraseña de sal y hash se guarda en la base de datos. La contraseña en sí no es

Dada la naturaleza sensible de la operación, quería asegurarme de que todo fuera kosher.

Nota: Utilizo la versión url safe de b64encode por hábito.

import hashlib import base64 import uuid password = ''test_password'' salt = base64.urlsafe_b64encode(uuid.uuid4().bytes) t_sha = hashlib.sha512() t_sha.update(password+salt) hashed_password = base64.urlsafe_b64encode(t_sha.digest())


En base a las otras respuestas a esta pregunta, he implementado un nuevo enfoque utilizando bcrypt.

Por qué usar bcrypt

Si entiendo correctamente, el argumento para usar bcrypt sobre SHA512 es que bcrypt está diseñado para ser lento. bcrypt también tiene una opción para ajustar qué tan lento quieres que sea al generar la contraseña hash por primera vez:

# The ''12'' is the number the dictates the ''slowness'' bcrypt.hashpw(password, bcrypt.gensalt( 12 ))

Slow es deseable porque si una parte malintencionada pone sus manos sobre la mesa que contiene contraseñas hash, entonces es mucho más difícil descifrarlas.

Implementación

def get_hashed_password(plain_text_password): # Hash a password for the first time # (Using bcrypt, the salt is saved into the hash itself) return bcrypt.hashpw(plain_text_password, bcrypt.gensalt()) def check_password(plain_text_password, hashed_password): # Check hased password. Useing bcrypt, the salt is saved into the hash itself return bcrypt.checkpw(plain_text_password, hashed_password)

Notas

Pude instalar la biblioteca bastante fácilmente en un sistema Linux usando:

pip install py-bcrypt

Sin embargo, tuve más problemas para instalarlo en mis sistemas de Windows. Parece necesitar un parche. Mira esta pregunta de : instalación de py-bcrypt en Win 7 64bit python


Lo más inteligente no es escribir el cripto pero usar algo como passlib: https://bitbucket.org/ecollins/passlib/wiki/Home

Es fácil estropear la escritura de su código criptográfico de una manera segura. Lo desagradable es que con un código no criptográfico, a menudo lo notas de inmediato cuando no funciona, ya que tu programa falla. Mientras que con el código criptográfico a menudo solo lo descubres después de que sea tarde y tus datos se hayan visto comprometidos. Por lo tanto, creo que es mejor usar un paquete escrito por otra persona conocedora del tema y que se basa en protocolos de batalla probados.

También passlib tiene algunas características agradables que hacen que sea fácil de usar y también fácil de actualizar a un nuevo protocolo hash de contraseña si un protocolo anterior resulta ser roto.

Además, solo una ronda de sha512 es más vulnerable a los ataques de diccionario. sha512 está diseñado para ser rápido y esto es realmente malo cuando intenta almacenar contraseñas de forma segura. Otras personas han pensado mucho sobre este tipo de cuestiones, así que será mejor que te aproveches de esto.



Para que esto funcione en Python 3 necesitarás codificar UTF-8 por ejemplo:

hashed_password = hashlib.sha512(password.encode(''utf-8'') + salt.encode(''utf-8'')).hexdigest()

De lo contrario, obtendrás:

Rastreo (llamadas recientes más última):
Archivo "", línea 1, en
hashed_password = hashlib.sha512 (password + salt) .hexdigest ()
TypeError: los objetos Unicode deben codificarse antes de hash


passlib parece ser útil si necesita utilizar hashes almacenados por un sistema existente. Si tiene el control del formato, use un hash moderno como bcrypt o scrypt. En este momento, bcrypt parece ser mucho más fácil de usar de Python.

passlib admite bcrypt, y recomienda instalar py-bcrypt como back-end: http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html

También puede usar py-bcrypt directamente si no desea instalar passlib. El archivo Léame tiene ejemplos de uso básico.

ver también: Cómo usar scrypt para generar hash para contraseña y sal en Python


EDITAR: Esta respuesta es incorrecta. No use un hash criptográfico para almacenar contraseñas. Use un hash de contraseña.

Se ve bien por mí. Sin embargo, estoy bastante seguro de que realmente no necesitas base64. Podrías hacer esto:

import hashlib, uuid salt = uuid.uuid4().hex hashed_password = hashlib.sha512(password + salt).hexdigest()

Si no crea dificultades, puede obtener un almacenamiento ligeramente más eficiente en su base de datos almacenando la contraseña saliente y hash como bytes sin formato en lugar de cadenas hexagonales. Para hacerlo, reemplace hex con bytes y hexdigest con digest .