Asegurar una API REST a nivel de mensaje

11

Me gustaría algún comentario sobre la siguiente idea de autenticación, ¿tiene sentido, y hay un estándar forma de hacer esto (o similar) para que pueda confiar en una implementación bien probada.

He visto muchas respuestas aquí sobre cómo asegurar la comunicación al servidor, y la mayoría de las respuestas son simplemente utilizar TLS correctamente. Estoy buscando una solución que permita encriptar y firmar los mensajes, para que el mensaje permanezca a salvo al pasar por el backend, hasta que lleguen al servicio de destino.

Context

  • Aplicación móvil para Android 2.3+ y iOS 6+ creada con phonegap (por lo tanto, las libs usadas deben poder utilizarse desde Java / obj-c o js)
  • La aplicación se comunica con el servidor mediante una API REST json
  • El contenido del mensaje debe permanecer confidencial a medida que pasa por el backend (sin terminación en el proxy / equilibrador de carga)
  • Debería ser compatible con "recordarme", para que el usuario no tenga que volver a ingresar su contraseña todo el tiempo
  • Todas las comunicaciones se realizan a través de ssl / tls

Autenticación

  • el cliente recopila las credenciales del usuario (nombre de usuario, frase de contraseña y alguna información de seguridad adicional)
  • el cliente genera una clave simétrica
  • el cliente cifra las credenciales con la clave simétrica
  • el cliente cifra la clave simétrica con la clave pública del servidor (enviada con el cliente)
  • el cliente envía el mensaje cifrado, la clave y el nonce a través de https (validando el certificado del servidor)
  • el proxy del servidor reenvía la solicitud de autenticación al servicio de autenticación
  • el servicio de autenticación descifra la clave y el mensaje simétricos
  • si las credenciales son válidas, el servicio genera un token de autenticación
  • el token está asociado a la clave simétrica en el servidor, si las credenciales no son válidas, la clave se descarta después de responder a la solicitud
  • el token se devuelve al usuario, cifrado con la clave simétrica
  • el token y la clave se almacenan localmente en el cliente, cifrados por una contraseña corta

Supongo que estas solicitudes están a salvo de los ataques de reproducción si se usa tls, por lo que no hay riesgo de que un atacante reproduzca el mensaje para obtener un token nuevo.

Otras llamadas a la API

  • el cliente genera los mensajes de solicitud, los cifra y firma el mensaje cifrado
  • el cliente envía el mensaje cifrado, el nonce y la firma con su token de autenticación al servidor
  • en la recepción, el servidor busca la clave asociada con el token recibido, verifica la firma y descifra el mensaje antes de procesarlo

Preguntas

  • ¿Hay algún problema con la reutilización de la misma clave simétrica?
  • ¿Qué es una buena elección de clave simétrica?
    • ¿Qué pasa con la firma AES-OCB o AES-CBC + HMAC?
  • ¿con qué frecuencia se debe cambiar la clave simétrica?
  • ¿Cuál es la mejor manera de actualizar las claves / actualizar tokens? Estaba pensando en emitir un token de actualización durante La respuesta de autenticación y las claves caducan después de un período específico, por lo que si el usuario no actualiza su Clave que tienen que iniciar sesión de nuevo.

Gracias

    
pregunta Nicolas Esteves 16.06.2013 - 22:05
fuente

2 respuestas

5

A menos que me haya perdido algo, su solución se ve muy mal como un servicio de token de seguridad. Para un STS, la clave es tener una parte que sea de confianza para identificar a la parte iniciadora de la parte que confía. En su caso, el agente de confianza y la parte que confía parecen ser la misma entidad.

Si su objetivo es que la confianza se propague al destino final, simplemente use SSL a través del proxy y use un certificado de cliente para identificar el punto final. Suponiendo que desea que HTTP pase a través de su proxy para que inspeccione el tráfico, implemente un STS estándar.

Como dijo Xander, REST es ideal para llamadas de servicio livianas, pero en el momento en que quiera hacer seguridad, debe usar SOAP, específicamente la extensión WS-Security. Realmente no es tan difícil, especialmente si controlas ambos extremos como lo haces. Consulte esta pregunta de desbordamiento de pila para saber cómo hacer esto en Java en Android.

Si continúa con su solución casera, vale la pena señalar que las últimas tres viñetas de su Autenticación parecen ser su punto débil.

    
respondido por el DodgyG33za 17.06.2013 - 11:02
fuente
2

No puedo decir que los haya revisado en detalle, pero puede que esté interesado en los intentos existentes para implementar la seguridad a nivel de mensaje en el nivel HTTP. Por ejemplo:

Ambos proyectos parecen inactivos. También pueden carecer del escrutinio experto que otros protocolos de seguridad suelen tener o deberían tener. Eso no quiere decir que haya algo malo con ellos. Yo sospecharía que la falta de éxito de HTTPsec se debe más bien a su llegada durante las "guerras SOAP vs REST" (agregando un poco de complejidad en el lado de REST) y el hecho de que solo tenía una implementación (en Java) con un no licencia libre.

Investigar si puede interesarle el cifrado y la firma de sus entidades de mensajes con herramientas existentes como OpenPGP.

RESTO es una palabra que tiene un significado diferente para varias personas. A veces, solo significa carga útil sobre HTTP, sin las múltiples capas de SOAP. Si dichos servicios siguen realmente los principios de HATEOS es otro asunto.

Mi opinión personal sobre esto es que la apatridia de REST debe aplicarse a las características principales de la aplicación, no necesariamente a sus aspectos de seguridad. Por supuesto, es muy difícil (si no imposible) evitar los ataques de repetición sin mantener algún tipo de estado en el lado del destinatario.

Dicho esto, no estoy seguro de que esté interesado en la seguridad de nivel de mensaje. Más bien, parece que está interesado principalmente en hacer un túnel de un equivalente de SSL / TLS a través de HTTP, porque no puede ejecutar una conexión TCP directa desde el cliente al servidor. Ya que también está utilizando SSL / TLS, esto sugiere que la razón principal de todo esto es que no confía en el equilibrador de carga. Tratar de escribir su propio protocolo es generalmente difícil y, a menudo, una mala idea. Las recomendaciones con respecto al cifrado y los algoritmos de MAC dependen de los detalles. (En comparación, se tardó un tiempo en identificar y solucionar algunos problemas con TLS, aunque es un protocolo abierto con una especificación detallada, estudiado por varios expertos).

    
respondido por el Bruno 17.06.2013 - 16:23
fuente

Lea otras preguntas en las etiquetas