La respuesta corta es que, obviamente, tienes un error (crítico) en tu código de hash. Tal como está, cualquiera puede probablemente iniciar sesión como cualquier usuario, porque por alguna razón, la función de hash de contraseña siempre produce el mismo resultado.
Hay varias maneras diferentes en que este error podría ocurrir, ninguna de las cuales es inherentemente obvia. Sin embargo, hay una cosa que considerar definitivamente: ¿está realmente incluyendo la contraseña en los datos que alimenta a la función hash, o está terminando el hash sin agregar la contraseña?
Otro riesgo es que el error está realmente en el código de su base de datos, y cuando está creando / actualizando el hash de la contraseña de un usuario, lo está configurando accidentalmente para los usuarios de todos , en lugar de solo el Una específica está siendo creada / actualizada. Esto es altamente explotable: creo mi propia cuenta y luego uso mi contraseña para iniciar sesión en una cuenta de usuario arbitrario, porque su hash se cambió al mío.
Bien, suficiente hipótesis. Lo realmente importante aquí es que, francamente, usted no debería escribir su propio sistema de autenticación. Incluso dejando de lado un error crítico que realmente, realmente nunca debería ocurrir, debería haberlo encontrado durante el desarrollo o las pruebas de unidades, si no otra cosa, su sistema simplemente no es seguro.
- No deberías usar MD5 para nada , tiene debilidades conocidas y se considera criptográficamente roto. Debería usar la familia SHA2 de funciones hash para cualquier cosa que necesite un hash rápido; incluso SHA1 se considera obsoleto para el nuevo código.
- Nunca debes usar un hash rápido para almacenar contraseñas. Las contraseñas se deben cifrar utilizando una función hash deliberadamente lenta y costosa, de modo que si alguien vuelca la base de datos de contraseñas, es difícil forzar la fuerza de las hashes de la contraseña que contiene, ya que cada ronda de forzar la fuerza lleva un tiempo.
- Usando un hash rápido de una sola ronda, el hardware básico (como las tarjetas gráficas de gama alta) puede calcular miles de millones de hashes por segundo, lo que permite el descifrado absurdamente rápido de contraseñas. En su lugar, utilice funciones destinadas a la generación de claves o al almacenamiento de contraseñas.
- PBKDF2 es el más común, pero también es el más antiguo y el que menos cantidad es mejor que un solo hash rápido. Bcrypt es mejor, pero contra el hardware moderno ya no es muy bueno. Scrypt, con los parámetros correctos, es la opción moderna generalmente aceptada. También existe Argon2, un nuevo algoritmo diseñado específicamente para el hash de contraseñas y el ganador de una competencia de tres años para determinar el mejor algoritmo de este tipo, si quiere ser vanguardista.
- No mencionas sales por usuario; ¿Los estás usando? La creación de contraseñas es absolutamente esencial, de lo contrario, un atacante puede generar una tabla de arco iris para cualquier esquema de hash que use. Las sales por usuario rompen este ataque, y también significan que (en situaciones normales) incluso si dos usuarios eligen la misma contraseña, no se puede decir que lo hicieron solo con mirar la base de datos; Sus hashes son diferentes. Todos los esquemas de hashing de buena contraseña toman un salt. Las sales deben generarse aleatoriamente y generalmente tienen una longitud de al menos 16 bytes (128 bits).
En este punto, realmente debo decir: debe usar un sistema de autenticación escrito por alguien que esté familiarizado con dichos sistemas y que tenga una versión bien probada lista para usar. No intente escribir tales características críticas para la seguridad hasta que comprenda mejor el área.