es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo hashear cadenas en python (django) y comparar el valor hasheado con una cadena dada.

Estoy trabajando en una aplicación web que permite a los usuarios registrarse y luego iniciar sesión, utilicé las siguientes funciones para cifrar la contraseña:

from passlib.hash import pbkdf2_sha256
import math

def encrypt_password(pswd):
    encrypt_pswd = pbkdf2_sha256.encrypt(pswd, rounds=(int(math.pow(len(pswd),3))), salt_size=(len(pswd)*2))
    return encrypt_pswd

def verify_password(pswd, e_pswd):
    en_pswd = encrypt_password(pswd)
    if en_pswd == e_pswd:
        return True
    else:
        return False

Mi problema es que la cadena que cifré no produce el mismo resultado cuando la cifro por segunda vez. ¿Cómo puedo resolver este problema o qué métodos puedo usar para cifrar la contraseña, almacenarla en la base de datos y comparar ese valor con el del formulario de inicio de sesión?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Existen algunos problemas con la implementación actual de las funciones encrypt_password y verify_password. El primer problema es que la función encrypt_password genera una nueva sal cada vez que se llama, lo que significa que la misma contraseña producirá un hash diferente cada vez que se le aplique el algoritmo de hash. El segundo problema es que la función verify_password utiliza la función encrypt_password para volver a aplicar el algoritmo de hash a la contraseña antes de compararla con el hash almacenado, lo que siempre dará como resultado un hash diferente, incluso si las contraseñas son iguales.

    Para resolver estos problemas, deberías generar una sal aleatoria cuando el usuario crea una cuenta, y luego utilizar esa misma sal para aplicar el algoritmo de hash a su contraseña cada vez que inicie sesión. Esto asegurará que la misma contraseña siempre produzca el mismo hash. Aquí tienes una implementación actualizada de las funciones:

    from passlib.hash import pbkdf2_sha256
    import secrets
    
    def encrypt_password(pswd, salt):
        encrypt_pswd = pbkdf2_sha256.encrypt(pswd, salt=salt, rounds=200000)
        return encrypt_pswd
    
    def verify_password(pswd, salt, e_pswd):
        return pbkdf2_sha256.verify(pswd, e_pswd, salt=salt)
    
    # Uso de ejemplo
    salt = secrets.token_hex(16)  # Genera una sal aleatoria de 16 bytes
    pswd = 'micontaseña'
    e_pswd = encrypt_password(pswd, salt)
    
    # Almacena la sal y el hash en la base de datos
    # ...
    
    # Más tarde, cuando el usuario inicie sesión:
    login_pswd = 'micontaseña'
    if verify_password(login_pswd, salt, e_pswd):
        # La contraseña es correcta, iniciar sesión del usuario
    else:
        # La contraseña es incorrecta, mostrar un mensaje de error
    

    En esta implementación actualizada, la función encrypt_password recibe un parámetro salt y utiliza esa sal para aplicar el algoritmo pbkdf2_sha256 al hash de la contraseña. Además, se ha establecido un número fijo de rondas para garantizar consistencia. La función verify_password utiliza la sal y el hash e_pswd almacenados en la base de datos, y verifica que la contraseña login_pswd coincida con el hash generado utilizando esa misma sal.

    Al utilizar un valor de sal fijo para cada usuario, puedes asegurarte de que la misma contraseña siempre produzca el mismo hash, y que la función verify_password verifique correctamente que la contraseña de inicio de sesión coincida con el hash almacenado.

Comments are closed.