Un poco de fondo primero:
La razón por la que las contraseñas no se almacenan como texto sin formato por lo general es para proporcionar defensa en profundidad. Es decir, en el caso de un compromiso de la base de datos (que es algo que obviamente debería evitarse), debería evitar que el atacante obtenga acceso a las contraseñas de usuario originales. Esto generalmente hace que obtener acceso a las contraseñas seguras PBKDF2 sea menos valioso para el atacante. Por supuesto, esto solo se aplica cuando las contraseñas son fuertes en sí mismas.
Para responder a tu pregunta:
Si el PBKDF2 se computó en el lado del cliente, una vez que el atacante obtiene acceso a la base de datos, el atacante puede utilizar la salida de PBKDF2 (almacenada en la base de datos) para iniciar sesión como usuarios víctimas a través de la interfaz web. Es decir, el atacante no necesita obtener acceso a la contraseña original para iniciar sesión. El atacante simplemente puede enviar el nombre de usuario y el valor PBKDF2 de la contraseña desconocido al servidor y registrarse como un usuario legítimo. La única diferencia es que el usuario legítimo utiliza JavaScript o algún otro mecanismo del lado del cliente para calcular el valor de PBKDF2 mientras que el atacante lo tendría en la base de datos.
Como resultado, la premisa original de hacer que el acceso a las contraseñas de hash sea menos valioso no se mantiene, ya que el acceso a esa información tiene valor (le da al atacante acceso a la cuenta de los usuarios víctimas). Tiene menos valor para el atacante que obtener acceso a la contraseña original (antes de realizar la operación PBKDF2) pero tiene más valor que si estuviera cifrada en el lado del servidor.
Hay otros problemas con el PBKDF2 del lado del cliente que creo que deberían mencionarse:
- se debería usar una sal estática (es decir, no puede ser aleatoria ya que produciría un valor PBKDF2 diferente)
- otros valores pasados a la función del lado del cliente PBKDF2 del cliente también deberían ser estáticos, por lo que se eliminan varias funciones de seguridad (como cambiar el número de iteraciones)
- al igual que en el caso de PBKDF2 del lado del servidor, la contraseña original se puede recuperar inyectando el código JavaScript para leer las palabras clave o los valores de entrada en el caso de un compromiso de la aplicación web (por ejemplo, XSS y varios otros vectores); de modo que las posibles ganancias de seguridad del PBKDF2 del lado del cliente se pierden