seguridad que generar crear con basada autenticación autenticacion c# iphone wcf web-services security

c# - que - Generación de tokens de autenticación criptográficamente seguros



token web service c# (7)

Amazon.com utiliza un token de mensaje HMAC SHA-1 para autenticar y autorizar solicitudes. Lo usan para un servicio comercial bastante grande, por lo que es probable que confíe en sus decisiones de ingeniería. Google publica la API OpenSocial que es algo similar. Basado en Google y Amazon.com, que utilizan enfoques similares y publicados abiertamente para asegurar las solicitudes web, sospecho que estas son probablemente buenas maneras de hacerlo.

Fondo:

Esta es realmente una pregunta general sobre mejores prácticas, pero algunos antecedentes sobre la situación específica pueden ser útiles:

Estamos desarrollando una aplicación "conectada" para el iPhone. Se comunicará con la aplicación de back-end a través de servicios REST. Para no tener que solicitar al usuario un nombre de usuario y contraseña cada vez que inician la aplicación, expondremos un servicio de "Inicio de sesión" que valida su nombre de usuario y contraseña en el inicio inicial y devuelve un token de autenticación que se puede usar para futuras aplicaciones web solicitudes de servicio para datos reales. El token puede tener un tiempo de vencimiento después del cual les pediremos que vuelvan a autenticarse con su nombre de usuario / contraseña.

La pregunta:

¿Cuáles son las mejores prácticas para generar este tipo de token que se utilizará para la autenticación?

Por ejemplo, podríamos ...

  • Hash (SHA-256, etc.) una cadena aleatoria y almacenarla en la base de datos para el usuario dado junto con una fecha de vencimiento. Realice una búsqueda simple del token en solicitudes posteriores para asegurarse de que coincida.
  • Cifre la identificación del usuario y alguna información adicional (marca de tiempo, etc.) con una clave secreta. Descifra el token en solicitudes posteriores para asegurarte de que fue emitido por nosotros.

Parece que debe ser un problema resuelto.


Con base en los comentarios de las otras respuestas a esta pregunta, investigación adicional y discusiones fuera de línea, aquí es lo que terminamos haciendo ...

Se señaló muy rápidamente que el modelo de interacción aquí es esencialmente el mismo que el modelo utilizado por Forms Authentication en ASP.NET cuando se marca una casilla de verificación "recordarme". Simplemente no es un navegador web que realiza las solicitudes HTTP. Nuestro "boleto" es equivalente a la cookie que establece la Autenticación de formularios. La autenticación de formularios utiliza esencialmente un enfoque de "cifrar algunos datos con una clave secreta" de manera predeterminada.

En nuestro servicio web de inicio de sesión, utilizamos este código para crear un ticket:

string[] userData = new string[4]; // fill the userData array with the information we need for subsequent requests userData[0] = ...; // data we need userData[1] = ...; // other data, etc // create a Forms Auth ticket with the username and the user data. FormsAuthenticationTicket formsTicket = new FormsAuthenticationTicket( 1, username, DateTime.Now, DateTime.Now.AddMinutes(DefaultTimeout), true, string.Join(UserDataDelimiter, userData) ); // encrypt the ticket string encryptedTicket = FormsAuthentication.Encrypt(formsTicket);

Luego tenemos un atributo de comportamiento de operación para los servicios WCF que agrega un IParameterInspector que busca un ticket válido en los encabezados HTTP para la solicitud. Los desarrolladores colocan este atributo de comportamiento de operación en las operaciones que requieren autenticación. Aquí es cómo ese código analiza el ticket:

// get the Forms Auth ticket object back from the encrypted Ticket FormsAuthenticationTicket formsTicket = FormsAuthentication.Decrypt(encryptedTicket); // split the user data back apart string[] userData = formsTicket.UserData.Split(new string[] { UserDataDelimiter }, StringSplitOptions.None); // verify that the username in the ticket matches the username that was sent with the request if (formsTicket.Name == expectedUsername) { // ticket is valid ... }


Crear su propio sistema de autenticación siempre es una "peor práctica". Ese es el tipo de cosa mejor para los profesionales que se especializan en sistemas de autenticación.

Si está empeñado en construir su propia arquitectura de "expirar ticket desde un servicio de inicio de sesión" en lugar de volver a utilizar una existente, probablemente sea una buena idea familiarizarse con los problemas que impulsaron el diseño de sistemas similares, como Kerberos. . Una introducción suave está aquí:

http://web.mit.edu/kerberos/dialogue.html

También sería una buena idea echar un vistazo a los agujeros de seguridad que se han encontrado en Kerberos (y sistemas similares) en los últimos 20 años y asegúrese de no replicarlos. Kerberos fue desarrollado por expertos en seguridad y revisado cuidadosamente durante décadas, y todavía se encuentran fallas algorítmicas graves en él, como este:

http://web.mit.edu/kerberos/www/advisories/MITKRB5-SA-2003-004-krb4.txt

Es mucho mejor aprender de sus errores que los tuyos.


Cualquiera de las dos respuestas que proporcionó será suficiente. Puede encontrar marcos que hagan esto por usted, pero la verdad es que no es tan difícil de construir. (Todas las empresas para las que he trabajado han hecho suyas). La elección de tokens almacenados en la base de datos frente a "cookies" de datos encriptados es una decisión arquitectónica. ¿Desea realizar una búsqueda en la base de datos en cada vista de página o preferiría? masticar CPU con descifrado de cookies? En la mayoría de las aplicaciones, el uso de cookies cifradas proporciona una ganancia de rendimiento a escala (si es una preocupación). De lo contrario, es solo una cuestión de gusto.



Esto simplemente suena como un identificador de sesión con un largo tiempo de caducidad. Los mismos principios utilizados para esto en aplicaciones web podrían aplicarse aquí.

En lugar de codificar información, los identificadores de sesión se eligen al azar de un espacio muy grande (128 bits). El servidor mantiene un registro que asocia el identificador de sesión con el usuario y otra información deseada, como el tiempo de caducidad. El cliente presenta el identificador de sesión sobre un canal seguro con cada solicitud.

La seguridad se basa en la imprevisibilidad de los identificadores de sesión. Genere con un RNG criptográfico, desde un espacio muy grande.


Ya que está usando WCF, tiene varias opciones si usa CFNetwork, por ejemplo NTLM o Autenticación implícita:

http://developer.apple.com/documentation/Networking/Conceptual/CFNetwork/Concepts/Concepts.html#//apple_ref/doc/uid/TP30001132-CH4-SW7

Sé que esto no responde a su pregunta específica, pero también me he enfrentado a este problema (iPhone - Tomcat) y he decidido usar los servicios de autenticación en el servidor web tanto como sea posible. No hay una penalización significativa por incluir la información de autenticación con cada solicitud en la mayoría de los casos. Un Google rápido aparece un montón de publicaciones en el blog sobre WCF y servicios RESTful (y algunas preguntas relacionadas en ).

¡Espero que esto ayude!