2012-06-15 17 views
6

Al autenticar a un usuario en un sitio web, ¿la generación de hash y la comparación deben hacerse en la base de datos o en el sitio web?¿Cuál es la mejor práctica para dónde se debe realizar la comparación de contraseña?

Mi argumento es que el sitio web debe pasar la contraseña proporcionada por el usuario (posiblemente encriptada por el servidor web) a la base de datos. La base de datos luego vuelve a encriptarlo con la sal y compara los hash. La base de datos responde al servidor web si las credenciales del usuario son válidas o no. De esta forma, el mínimo deja la base de datos, esencialmente un sí o un no, ninguna de la información almacenada de las credenciales. Lo malo es que la base de datos tiene que hacer más trabajo.

El otro argumento es que el trabajo debe realizarse en el servidor web. Aquí, el servidor web crearía el hash y solicitaría el hash almacenado de la base de datos y lo compararía. En esta situación, la sal debe pasar de la base de datos al servidor web para que se cree el hash. pero el trabajo se comparte a medida que aumenta el número de servidores web.

Personalmente veo el segundo método como un posible riesgo de seguridad. En caso de comprometer el servidor web, se pueden solicitar sales y hash desde la base de datos y descifrarlo fácilmente.

¿Cuál es la mejor práctica para realizar la operación anterior? ¿Estoy pasando por alto/me estoy perdiendo algo?

Gracias

Respuesta

3

El primer problema que sospecho que se encontrará (y es uno grande) es que su base de datos no tiene una función de contraseña de hash. Claro, probablemente tiene MD5() y SHA1(), pero estas son funciones hash criptográficas. ¿Tiene bcrypt() o scrypt() o PBKDF2()?

Usar una función hash criptográfica en lugar de una función hash de contraseña es lo que significaba que las contraseñas de LinkedIn se podían descifrar rápidamente. Si no usa una de las funciones anteriores, será igualmente vulnerable si se filtran sus hash.


Pasando a responder a su pregunta si se asume que la base de datos hace ayuda de un algoritmo de hash de contraseñas (usando bcrypt simplemente porque tengo que escoger uno).Las dos alternativas son:

hash en la base de datos:

$db->query("SELECT COUNT(*) FROM users WHERE username = '?' AND password = BCRYPT(?, (SELECT salt FROM user WHERE username = '?'))", $username, $password, $username); 
if($row['count'] != 1) 
{ 
    // Not authenticated. Throw exception. 
} 

En este caso, la contraseña prima se envía a la base de datos y un simple sí o no (1 ó 0) se devuelve. Esta comunicación de base de datos puede ser encriptada. El hash y la sal nunca se guardan en la aplicación.

Hashing en la aplicación:

$db->query("SELECT username, salt, password FROM users WHERE username = '?', $username); 
if(bcrypt($password, $row['salt']) != $row['password']) 
{ 
    // Not authenticated. Throw exception. 
} 

En este caso, el hash y la sal se extraen de la base de datos en la aplicación y el hash de la contraseña cruda y la comparación se realiza allí. La comunicación a la base de datos todavía se puede encriptar. La contraseña sin formato nunca se guarda en la memoria de la base de datos.

Para mayor eficiencia, podemos suponer que ambos algoritmos de hash están escritos en C (o en algún lenguaje compilado) y es posible que los proporcione el sistema operativo, por lo tanto, tome el mismo tiempo. La opción de hash de la aplicación recibe más datos a través de la conexión y la opción de hashing de la base de datos envía más y tiene una consulta más compleja (esencialmente dos consultas, una para obtener la sal y otra para efectuar la comparación). Puede que no sea posible usar un índice de la forma en que he escrito esa consulta, pero la consulta podría reescribirse. Dado que el tamaño de los datos en ambos casos probablemente aún sea un paquete TCP, la diferencia de velocidad será insignificante. Yo llamaría a esto una victoria para la opción de hashing de la aplicación debido a la subconsulta.

Para la exposición. Considero que la contraseña sin procesar es más sensible que el hash y la sal juntos. Por lo tanto, limitar la exposición de la contraseña sin procesar parece ser la apuesta más segura, lo que hace que el hashing de aplicaciones sea la mejor práctica.

+0

Supongo que simplifiqué el ejemplo pero aún podría incrustar el método de cifrado en la base de datos, por ejemplo, usar objetos clr en el servidor sql – Blootac

+0

@Blootac Buen punto. He agregado una respuesta a la pregunta real con la suposición de que su base de datos tiene un algoritmo hash apropiado. – Ladadadada

+0

Gracias, buena descripción de pros y contras. – Blootac

3

están pasando por alto el propósito de una sal.

Una sal se utiliza para evitar un ataque de diccionario contra contraseñas hash. Si su contraseña es "maní" y hash a 12345, puedo pregenerar una lista de hashes para cada palabra en un diccionario (incluida su contraseña) y encontrar rápidamente su contraseña haciendo una búsqueda en contra de mi conjunto de contraseña pregenerado hashes. Esto es lo que le sucedió a LinkedIn recientemente. Si las contraseñas están en sal, tendré que pregenerar un diccionario para cada valor de sal después de poniendo en peligro la base de datos, lo que sería prohibitivamente caro.

Además, las sales apropiadas generadas al azar evitan que un atacante sepa que usted y yo tenemos la misma contraseña (sin la sal, tendríamos el mismo hash).

Mi punto es que las sales no están destinadas a ser un secreto. No son información pública, pero un atacante que obtiene acceso a los valores de sal + hash no significa necesariamente que las contraseñas se hayan visto comprometidas.

0

Una buena regla general para la seguridad informática es que, si tiene que preguntar, no debe hacerlo usted mismo. Pero si su preocupación es la exposición de los detalles de la contraseña si el servidor web está en peligro, entonces un enfoque es mover la autenticación a su propio sistema y no darle acceso al servidor web a la base de datos de contraseñas.

+2

Veo su punto, pero si nadie hace preguntas, nadie aprende y la gente continuará haciendo las cosas mal. Son las personas que no hacen las preguntas que deberían preocuparse más. Gracias por su sugerencia. – Blootac

Cuestiones relacionadas