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.
No quiero resucitar un hilo viejo, pero ... cualquiera que quiera usar una solución segura moderna y actualizada, use argon2.
https://pypi.python.org/pypi/argon2_cffi
Ganó la competencia de hash de contraseñas. ( https://password-hashing.net/ ) Es más fácil de usar que bcrypt, y es más seguro que bcrypt.
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
.