Autenticación segura usando Ajax

Transcripción

Autenticación segura usando Ajax
Autenticación segura usando Ajax
Escrito por edgaragg
Martes, 14 de Abril de 2009 10:26 - Actualizado Martes, 14 de Abril de 2009 15:07
Los ultimos días he estado dedicado a investigar un poco acerca de un problema que a estado
dando vueltas en mi cabeza. Hace un tiempo apareció una noticia acerca de un nuevo ataque
que hace al protocolo SSL inseguro. Especificamente en Black Hat 2009 , se publicó la
herramienta SSLStrip que permite realizar un ataque de tipo "man in the middle" engañando al
usuario para hacerlo creer que se encuentra en un sitio de Internet con cifrado SSL (HTTPS).
En realidad tus datos se están transmitiendo sin cifrado alguno (HTTP), pero la cosa no para
ahí, SSLStrip también permite engañar el servidor HTTP, haciéndolo pensar que el cifrado ha
sido anulado pero en realidad el sitio sigue como si todavía utilizara SSL.
Si esto es así, resultaría realmente fácil obtener las contraseñas de cualquier sitio web. Entonces ¿cómo podemos protegernos?
Investigando un poco he dado con una solución que si bien no es perfecta me parece que es lo
suficientemente segura para ser incluso usada sin necesidad de SSL. La solución está basada
en el uso de autenticación por desafio/respuesta y mi propuesta se usa en combinación con
AJAX para el intercambio de información con el servidor.
En primer lugar voy a explicar en que consiste la autenticación por desafío/respuesta y
posteriormente pasaré a dar una explicación del algoritmo propuesto, así como algunas
recomendaciones que tomo en cuenta actualmente para proveer de mayor seguridad el
proceso de autenticación.
¿Qué es la autenticación por desafío/respuesta?
La autenticación por desafío/respuesta (CRA por sus siglas en inglés) es un método que
permite prover la identidad de un usuario a través de un medio inseguro sin revelar información
sensible que pueda ser usada por usuarios malintencionados para impersonar la identidad de
otros usuarios.
Este método hace uso de los algoritmos de encriptamiento de una sola vía o de hash, como por
ejemplo MD5, SHA-1 o SHA-512 y funciona de la siguiente manera:
1/4
Autenticación segura usando Ajax
Escrito por edgaragg
Martes, 14 de Abril de 2009 10:26 - Actualizado Martes, 14 de Abril de 2009 15:07
Supongamos que tenemos una función de hash h(), cuando el cliente se conecta al servidor,
este genera un valor X de forma aleatoría conocida como el desafío. Este desafío es enviado
al cliente. Cuando el cliente tiene el valor de X calcula h(P+X) donde P es el password o
contraseña y + es la concatenación de cadenas. Este valor es la respuesta al desafío y se
envía al servidor junto con el nombre de usuario. Luego el servidor calcula de nuevo el valor
h(P+X) para el nombre de usuario enviado y lo compara con el valor que envió el cliente, si
coinciden entonces el usuario queda autenticado.
Como puede verse la contraseña nunca es enviada al servidor, en su lugar se envia un valor
encriptado en una sola vía, por lo que la única forma de obtener la contraseña es usando
fuerza bruta. La otra ventaja es que el valor encriptado solo es valida para esa sesión puesto
que si el mismo usuario intenta autenticarse posteriormente en otra sesión, se generaría otro
desafío y como resultado se obtendría otra resuesta.
Algoritmo propuesto.
En primer lugar debo indicar que actualmente no acostumbro a almacenar la contraseña de
ningún usuario como texto plano. En su lugar la contraseña del usuario es almacenada usando
un algoritmo de hash en combinación con un valor aleatorio generado al momento del registro
del usuario conocido como salt. Esto provee una seguridad extra puesto que hace
practicamente imposible obtener la contraseña de los usuarios si por alguna razón un atacante
obtiene acceso al servidor (y especificamente a la tabla de usuarios en la base de datos)
De esta manera el pseudo-algoritmo indicado en el apartado anterior se ve modificado para
aceptar el uso del valor salt.
El algoritmo de autenticación sería el siguiente:
1. Una vez que el usuario llena el formulario de autenticación y presiona el botón para hacer
login, se hace una llamada usando ajax enviando unicamente el nombre del usuario.
2. El servidor valida la existencia del usuario, en caso de que el usuario exista se crea un
valor aleatorio (el desafío) y se envía al cliente conjuntamente con el valor salt del usuario, el
cual será usado para obtener el valor de la contraseña encriptada en el servidor. El valor del
desafío se almacena en sesión.
3. El cliente obtiene el valor de la contraseña encriptada, primero concatenando el valor del
2/4
Autenticación segura usando Ajax
Escrito por edgaragg
Martes, 14 de Abril de 2009 10:26 - Actualizado Martes, 14 de Abril de 2009 15:07
salt y posteriormente aplicandole la función de hash. En otras palabras:
Contraseña encriptada = h(contraseña + salt)
4. Se concatena el valor del desafío con la contraseña encriptada, obteniendose así el valor
de la respuesta al desafío. En otras palabras:
Respuesta desafío = h(contraseña encriptada + desafío)
5. La respuesta es enviada al servidor en conjunto con el nombre de usuario usando otra
llamada ajax.
6. El servidor calcula la respuesta al desafío de forma similar al paso 4, con la diferencia de
que la contraseña encriptada es la almacenada en la base de datos para ese usuario.
7. El servidor compara el valor de la respuesta calculado con el enviado por el cliente. Si
coinciden entonces el cliente conoce la contraseña del usuario y por lo tanto el mismo esta
autenticado. En caso contrario la autenticación falla.
En el paso 5 no es 100% necesario efectuar otra llamada ajax, podría hacerse un Post de un
formulario, pero en este caso hay que asegurarse (usando JScript) que se envíe la respuesta
del desafio y se evite enviar la contraseña en claro. Lo que si es importante es hacer la
llamada Ajax en el paso 1 con la intención de obtener el valor del salt y el desafío.
Registro de usuario seguro
Ahora tenemos un proceso de autenticación en principio segura, sin embargo, no es el único
lugar en la aplicación donde un usuario puede enviar una contraseña como texto a través de la
red. Esto puede pasar también en el momento del registro, por lo que este proceso también
debe llevarse a cabo de forma segura. A continuación presento un algoritmo para llevar a cabo
el registro del usuario de forma segura, este proceso debe hacerse de una forma muy similar
para el caso de cambio de contraseña:
1. El cliente llena los datos de registro y presiona el botón para registrar. Al hacer clic sobre
dicho botón se hace una llamada ajax al servidor enviando como parámetro unicamente el
nombre de usuario (Puede enviarse también el correo electrónico si se desea validar que el
correo sea único)
2. El servidor valida que el nombre de usuario no este repetido. (tambien verifica el correo si
este fué enviado) Si no está repetido se genera un código aleatorio que será el salt y se envía
al cliente.
3. El cliente encripta la contraseña concatenandola con el salt y aplicandole posteriormente
la función de hash. En otras palabras:
3/4
Autenticación segura usando Ajax
Escrito por edgaragg
Martes, 14 de Abril de 2009 10:26 - Actualizado Martes, 14 de Abril de 2009 15:07
Contraseña encriptada = h(contraseña + salt)
4. Se envía la contraseña encriptada al servidor junto con los otros datos del registro
haciendo otra llamada ajax.
5. El servidor almacena los datos del usuario junto con la contraseña encriptada.
En este caso, en el paso 4 se puede cambiar la llamada ajax por un post de un formulario. De
ser así, hay que asegurarse de enviar la contraseña encriptada en lugar de la contraseña en
texto plano.
¿Cómo encriptar en el cliente?
El último obstaculo que debemos superar es como hacer la encriptación en el cliente. Es
recomendable usar un algoritmo de encriptación reconocido como MD5 o SHA1, SHA256 o
SHA512 en lugar de implementar uno por cuenta propia.
Como la encriptación se debe llevar a cabo del lado del cliente hay que usar Javascript para
llevarla a cabo. Se puede conseguir la implementación de los algoritmos en Internet. Aqui hay
algunos enlaces donde se pueden conseguir:
Implementación de SHA-256, SHA-384 y SHA-512
Implementación de MD5 y SHA-1
Las implementaciones de MD5 y SHA-1 tambien posee funciones para aplicar el mecanismo de
HMAC, el cual es bastante seguro y puede ser usado en una variación de los algoritmos
propuestos anteriormente.
4/4

Documentos relacionados