Para comprender este problema, primero debe comprender por qué las contraseñas de hash. Es completamente posible almacenar una contraseña en texto plano en un servidor y simplemente comparar la contraseña transmitida a la contraseña recibida. Mientras la contraseña esté protegida en tránsito, este es un medio seguro de autenticación (secreto compartido).
La razón por la que las contraseñas están en hash es porque el problema no es la autenticación, sino el almacenamiento. Si el servidor alguna vez se ve comprometido, el atacante tendría acceso inmediato a todas las cuentas de usuario, ya que ahora sabrían el secreto utilizado para la autenticación de los usuarios.
Hashing actúa como una barrera para esto. Dado que el servidor no conoce la entrada real requerida para la autenticación, incluso un compromiso con la base de datos no otorga a un atacante acceso a las cuentas de usuario. Todavía tendrían que averiguar la entrada para dar para alcanzar los valores hash con los que la aplicación verifica. Claro que podrían alterar todos los valores a algo que saben, pero esto generaría sospechas rápidamente y el sistema se cerraría y se aseguraría.
Entonces, el problema con el hashing del lado del cliente es que efectivamente hace que el resultado del hash sea la contraseña en lugar de la contraseña. No hay nada que impida que un atacante omita al cliente oficial y simplemente envíe el hash final al servidor directamente. No proporciona seguridad adicional (o pérdida) durante la autenticación, pero en la situación en la que el hash está diseñado para proteger, no ofrece nada, ya que el hash almacenado en la base de datos es en realidad el secreto compartido transmitido al servidor.
Dicho esto, hay dos cosas notables que el hashing del lado del cliente te da. Si bien no ayuda en absoluto a proteger su sistema, puede ayudar a proteger a su usuario. Si no está transmitiendo la contraseña con seguridad o si la transmisión se ve comprometida sin que el código del cliente se vea comprometido, seguirá protegiendo la contraseña del usuario (que pueden reutilizarse en otros sitios) para evitar que se filtre.
La otra es que puede proporcionar iteraciones adicionales de un hash para hacer que un ataque fuera de línea contra la base de datos sea más difícil sin tener que usar ciclos de servidor, pero aún necesita suficientes ciclos de servidor para protegerse contra un cliente no autorizado. Una vez más, la protección principal que ofrece esta es evitar que se descubra la contraseña original, pero no hace nada para ayudar a proteger el mecanismo de autenticación de su sitio.
Dicho de otra manera, si bien proporciona algunas protecciones menores, desde el punto de vista del servidor, el hash del lado del cliente debe tratarse como si fuera la contraseña directa del usuario. No proporciona ni más ni menos seguridad en el servidor que si el usuario hubiera dado su contraseña directamente y debería estar protegido como tal.
Si desea poder proporcionar ese nivel adicional de seguridad, recomendaría dos hashes. Hash una vez del lado del cliente para crear una contraseña nueva y única, luego hash esa contraseña en el servidor para hacer un valor que almacena en la base de datos. De esta manera obtienes lo mejor de ambos mundos.
En su mayor parte, se confía en SSL lo suficiente como para proteger el intercambio de que el hash inicial antes de la transmisión se considera innecesario y un servidor comprometido siempre podría alterar el código enviado al cliente para que no se realice el hash inicial . Simplemente no es una alternativa efectiva a SSL y no ofrece suficiente ventaja adicional para valer los costos y la complejidad.