Protocolo de acuerdo de clave en una API REST

4

Tengo una API REST de C # que expone algunos métodos a través del protocolo HTTP. La API está destinada a ser utilizada en mi aplicación de Android (Java) que se encuentra actualmente en los cimientos.

Dado que la aplicación se encuentra en una etapa temprana de desarrollo y aún no se ha lanzado, accedo a los métodos de API usando http://example.com/resources/item17 sin ninguna seguridad adicional. Sin embargo, tan pronto como se lance la aplicación, no quiero que nadie excepto los usuarios de mi aplicación accedan a la API.

Mi idea es generar algún tipo de clave única en mi código C # + de Android. Una versión simplificada para darle la idea:

int key = DateTime.Now.Minute * Math.PI * 5;

Esto haría que la solicitud se vea algo como:

'http://example.com/resources/item17?key=1234567'

La API de C # verificará esto antes de enviar una respuesta.

La única forma de averiguar cómo se genera la clave sería revertir mi código de Android (que será confuso en ese momento).

¿Esto suena como una buena solución, o tienes alguna otra sugerencia?

    
pregunta Johan 11.10.2013 - 17:03
fuente

4 respuestas

3

Su solución se basa en la suposición de que la ingeniería inversa de una aplicación confusa es difícil. Sin embargo, este supuesto no coincide con la experiencia. Por lo tanto, uno no puede realmente decir que su solución es buena .

Sin embargo, tal vez su solución sea la mejor que se pueda hacer (no es lo mismo que "bueno"). La alternativa es la autenticación del usuario. Es decir, cada aplicación instancia obtendría su propia clave de autenticación; entonces, depende del servidor aceptar una clave o rechazarla. Esto le da la capacidad de revocar una clave que parece haber sido diseñada por ingeniería inversa; También puede darle un apalancamiento legal para procesar a los infractores.

Si persigue el concepto de generar una clave basada en el tiempo en la aplicación, al menos hágalo con las herramientas criptográficas adecuadas. En este caso, use HMAC : codifique la hora actual en algunos bytes, luego calcule HMAC / SHA-1 (o HMAC / SHA-256, lo que sea más fácil para usted) en estos bytes, usando una clave codificada. La clave codificada es el objetivo de la ingeniería inversa. El uso de HMAC al menos lo protegerá de la reconstrucción de claves mediante el análisis de la salida: el atacante realmente tendrá que hacer un desmontaje del código real. También necesitará la aplicación para enviar su noción de "hora actual" como parámetro adicional, porque no puede confiar en que el dispositivo cliente esté bien sincronizado.

(Nada de esto es exclusivo con la ejecución completa de HTTPS, lo que suele ser una buena idea cuando importa la seguridad, pero en realidad es otro tema aquí).

    
respondido por el Thomas Pornin 11.10.2013 - 17:48
fuente
2
  • Primero, use https (SSL / TLS)
  • En segundo lugar, puedes tener ataques de reproducción enlace

Creo que necesitas usar un método de autenticación y autorización más sólido. Debido a que es tu propia API, no necesitas auth.

Pruebe una de estas opciones, todas dependen del nivel de seguridad que necesite.

  • HTTP Basic + TLS (con claves en lugar de contraseñas)
  • Application-only-auth enlace
  • Amazon Signature Versión 4 enlace
respondido por el Diego Alvarez 11.10.2013 - 17:44
fuente
1

Para mí, esto suena como desarrollar tu propio algoritmo cryto. Puede evitar "algunos" al ofuscar el código de Android, sin embargo, cualquier análisis dinámico del código puede revelar en cierta medida la aleatoriedad de la clave. Además, las claves en la solicitud GET se pueden interceptar simplemente usando un proxy intermedio (incluso dentro de SSL / TLS, el proxy intermedio puede ser una CA válida en el dispositivo)

No se me ocurre nada que pueda detener a alguien para falsificar la solicitud y replicarla desde una computadora de escritorio. Sin embargo, para dificultar las cosas para alguien que quiera acceder a la API, limite directamente el número de solicitudes por sesión autenticada que es la mejor manera de ganar.

    
respondido por el Malach 11.10.2013 - 17:39
fuente
1

Parece que una persona motivada podría determinar la clave si quisiera.

¿Sería posible enviar una clave única junto con cada instancia de la aplicación cuando se descarga? Un GUID o un UUID podrían ser buenos para esto y sería mucho más difícil de predecir. Cuando alguien descargó la aplicación, enviaría esa clave junto con la instancia y luego la insertaría en una base de datos que usted controla.

Luego, cuando se envía una solicitud, puede confirmar que existe en la base de datos. Esto también le permitiría hacer un seguimiento del número de solicitudes provenientes de una clave específica.

Con el original, cualquier forma de identificar si el código se ha comprometido. Por ejemplo, si tiene 100 usuarios y recibe 1000 solicitudes por día y luego llega a más de 1100 solicitudes por día, lo que probablemente se vería normal. Si identifica la cantidad de solicitudes de cada clave, verá que normalmente recibe 10 solicitudes al día de cada una de sus claves, pero si aumenta hasta 1100 solicitudes y un solo usuario pasa de 10 a 110 solicitudes, probablemente pueda decir esa esa clave se vio comprometida y la deshabilita.

    
respondido por el Abe Miessler 11.10.2013 - 17:32
fuente

Lea otras preguntas en las etiquetas