Exponer la contraseña simple siempre es un problema, a veces más y otras menos. Si el atacante logra poner en peligro el servidor, podría agarrar las contraseñas cuando el servidor compruebe si son correctas. Registros de depuración extensos similares en el servidor también podrían registrar inadvertidamente las contraseñas ingresadas, de modo que un atacante podría tomarlas del disco del servidor o de copias de seguridad externas.
Por lo tanto, podría ser una buena idea proteger la contraseña contra el servidor también. Solo que esto no es fácil, ya que el servidor finalmente necesita la contraseña o algo equivalente para autenticar al usuario.
Una forma no sería enviar la contraseña original del cliente al servidor, sino usar un algoritmo para obtener la contraseña del lado del servidor de la contraseña ingresada por el usuario, una función de derivación de claves (KDF). Esto es como sugieres con h(p)
. Por supuesto, esta clave derivada debería tener la misma protección del lado del servidor que tendría una contraseña de texto simple, ya que es esencialmente una contraseña de texto simple, pero no tan fácil de adivinar. Esto significa que la clave derivada debe almacenarse correctamente con contraseña con hash en el lado del servidor. Si esta clave derivada depende del dominio de los servidores o de cualquier otra cosa específica del sitio, al menos podría proteger un poco contra la reutilización de la contraseña, ya que la misma contraseña dará como resultado una clave derivada diferente según el sitio. Por supuesto, si la clave se obtiene a partir de la clave en el código provisto por el servidor, entonces un atacante podría cambiar este código para obtener también la contraseña original, pero esto requiere más esfuerzo y, por lo tanto, este método reduce el riesgo total.
Aún mejor sería si la contraseña solo se usa localmente en el cliente para proteger un certificado de cliente dentro del navegador y luego usar la autenticación mutua en https. En este caso, no sería suficiente que el atacante atacara el servidor, pero cada cliente tendría que ser atacado. Por otro lado, los certificados del lado del cliente son más una molestia que emplear que una simple contraseña y, por lo tanto, rara vez se utilizan. En otras palabras: menos riesgo a costa de menos facilidad de uso.
Aparte de eso, también hay métodos de desafío-respuesta como Digest-MD5. Solo estas funciones de resumen tienen el problema de que la contraseña del usuario o algo equivalente deben almacenarse en el lado del servidor sin la protección que ofrece el hashing de contraseña unidireccional habitual, lo que aumenta la superficie de ataque allí.