Formas de autenticar al cliente con un servidor

2

Tengo una aplicación que envía un mensaje cifrado al servidor, con el nombre de usuario del remitente y el destinatario adjuntos. Los nombres de usuario están vinculados a una ID de dispositivo única que permite que se les envíen mensajes a través del servicio de mensajería en la nube de Google.

Mi problema es que no estoy seguro de cuál es la mejor manera de evitar que alguien falsifique mensajes en el servidor y escriba cualquier nombre de usuario posible en el campo del remitente.

Esperaba poder usar una clave secreta almacenada en el código de la aplicación, que es lo mismo que una clave almacenada en el servidor correspondiente a un usuario específico, pero desde entonces he descubierto que esta clave sería propensa a ser descubierta. a través de la ingeniería inversa de la aplicación.

Así que ahora la única solución aparente para mí es implementar un sistema basado en contraseña que genere una clave de sesión de tiempo limitado en el servidor que el cliente recupera después de enviar la contraseña correcta, y luego se envía junto con cada mensaje posterior. / p>

Sin embargo, preferiría evitar este tipo de sistema, ya que quiero mantener la aplicación lo más simple posible, y evitar tener que implementar sistemas de contraseña olvidados y demás.

¿Hay alguna otra forma en la que pueda garantizar que los mensajes son auténticos?

    
pregunta JackWoot 28.01.2014 - 03:35
fuente

2 respuestas

2

Desde el punto de vista criptográfico, si un usuario A debe poder hacer algo que otro usuario B no puede (por ejemplo, enviar un mensaje con " A "como nombre del remitente), entonces debe haber algún valor que A sepa pero B no. Ese tipo de valor secreto se denomina clave , aunque existen otras terminologías (por ejemplo, "contraseña" cuando el secreto se almacena en un cerebro humano).

La ocultación de claves dentro del código de la aplicación tiene dos grandes inconvenientes:

  • Se pueden recuperar mediante ingeniería inversa.
  • No son específicos del usuario.

Sin embargo, en su caso, desea un valor secreto específico del usuario: cada usuario tiene su propia clave, con la que se autentican sus mensajes. Por lo tanto, la clave del usuario no puede ser codificada en el código de la aplicación compilada; sin embargo, puede almacenarse como un archivo en el dispositivo del usuario. La ingeniería inversa no es un problema: mediante la ingeniería inversa de la instalación de su propia aplicación, el usuario puede aprender su propia clave, no la clave de otra persona.

El punto importante aquí: dicha clave autentica al usuario , no al dispositivo . Asegurarse de que un mensaje dado provenga de un dispositivo específico, y enviado por "su aplicación no modificada" y no por otro código, es casi imposible, ya que dicho dispositivo está físicamente en manos del usuario, y no es a prueba de manipulaciones Para obtener este tipo de garantía, necesita un dispositivo que pueda luchar contra su propietario, por ejemplo. una tarjeta inteligente . La facturación de los teléfonos móviles funciona de manera práctica y legal, porque el usuario no puede acceder a su propia tarjeta SIM. No puede tener este modelo con una aplicación que sea solo de software en hardware no blindado (el propio teléfono).

Sin embargo, siempre que desee autenticar usuarios, no dispositivos, entonces una clave específica del usuario está bien.

Luego viene la parte difícil: la autenticación es buena, pero ¿quién la está haciendo?

Si solo quiere que su servidor se asegure de la identidad de A , entonces un secreto compartido entre A y el servidor S puede estar bien. La herramienta criptográfica subyacente sería un MAC . Sin embargo, en ese caso, cuando el usuario A envía un mensaje al usuario B a través de su servidor, el servidor está seguro de que efectivamente habla con A , pero B no sabe nada. Un usuario malvado E , que desea falsificar un mensaje falso que supuestamente proviene de A , puede enviar dicho mensaje directamente a B , sin pasar por su servidor en absoluto!

Una solución, en ese caso, es hacer que la comunicación de S a B se autentique por igual con la tecla B : esta vez, es B quien se asegura de que lo que recibe de S sea de S . Con MAC aplicado en ambas direcciones, para todas las comunicaciones entre el servidor y cualquier usuario, puede tener una red de mensajería razonablemente segura. Por supuesto, S es de confianza : su servidor puede traicionar a todos a voluntad. Pero tal vez esto no sea un problema para ti.

(Para la autenticación de extremo a extremo, sin confiar en un servidor central, tendría que recurrir a la criptografía asimétrica y firmas digitales , y las cosas se vuelven mucho más complejas.)

El almacenamiento de una clave específica del usuario en un archivo en el dispositivo del usuario parece bastante simple. Sin embargo, a veces, los usuarios cambian de dispositivo (por ejemplo, compran un teléfono nuevo o son adictos a Apple que tienen un iPhone y un iPad) y aún desean conservar su identidad . Esto implica que la clave específica del usuario de alguna manera viaja desde un dispositivo al usuario.

El esquema que usted visualiza (almacenar la clave en el propio servidor, con descarga automática después de la autenticación basada en contraseña) es válido. Asegúrate de hacerlo sobre SSL, por supuesto. Puede combinarlo con un mecanismo de almacenamiento en caché: la aplicación descarga la clave cuando aún no la tiene, pero luego la almacena en el dispositivo.

    
respondido por el Thomas Pornin 28.01.2014 - 14:54
fuente
0

Ya que es una aplicación, ¿asumo que es para dispositivos móviles? En ese caso, es altamente recomendable utilizar el protocolo TLS bien establecido. Proporciona confidencialidad, autenticación de mensajes e integridad mediante el uso de códigos de encriptación y autenticación de mensajes (MAC). No requiere que se almacenen claves en su aplicación si compra un certificado de clave pública para su servidor. Además, hay bibliotecas SSL / TLS disponibles para Android SDK e iOS.

De lo contrario, si implementa su propio esquema de autenticación de mensajes y protocolo de intercambio, puede que no sea lo suficientemente seguro y propenso a errores de implementación.

    
respondido por el jingyang 28.01.2014 - 06:21
fuente

Lea otras preguntas en las etiquetas