He leído algunos ejemplos sobre SO para asegurar el cliente / datos. Pero tenemos un problema un poco diferente y no estamos seguros de dónde buscar.

Básicamente, tenemos un juego de Android que es un juego basado en la ubicación geográfica. Usamos HMAC-SHA1 en la cadena de consulta para verificar que los datos que se envían desde el cliente son, de hecho, del cliente. Hay un pequeño problema. La clave HMAC-SHA1. Puedo ofuscarme hasta que mi corazón esté contento, pero la clave permanece en la aplicación. Alguien puede descompilar fácilmente la aplicación, tomar la clave y luego enviar consultas manuales mediante un navegador para su cuenta de usuario (suplantación de GPS).

Vi un ejemplo en el que alguien sugirió la autenticación ssl del lado del cliente y del servidor. No estoy seguro de cómo funcionaría, ¿no solo necesitaría adjuntar un certificado ssl a la aplicación? ¿Esto no estaría sujeto a la descompilación también, requeriría que el usuario final vuelva a compilar / usar el certificado?

¿Podemos de alguna manera usar el administrador de paquetes para obtener el certificado autofirmado? Necesito encontrar la forma correcta de asegurar nuestra transmisión para que alguien no pueda falsificar sus transmisiones para su propia cuenta de usuario.

Gracias

1
Chrispix 22 abr. 2012 a las 20:34
Entonces, encontré esto: stackoverflow.com/ preguntas / 5578871 /… Pero parece que cualquiera puede obtener el hash de su propia aplicación firmada, utilizando los mismos métodos. Eso parece un poco fastidioso. ¿Alguna otra idea?
 – 
Chrispix
22 abr. 2012 a las 23:52

1 respuesta

La mejor respuesta

Para autenticar al cliente, necesita algún tipo de credencial. Tu también puedes:

  1. no guarde las credenciales y haga que el usuario las ingrese cada vez
  2. guárdalos en algún lugar
  3. usar credenciales del sistema
  4. utilizar alguna forma de proveedor de identidad

1 es un inconveniente, 2 estoy sujeto a ataques siempre que alguien tenga acceso físico al dispositivo. Para 3, puede usar la cuenta de Google del usuario para estar (bastante) seguro de quiénes son y bloquearlos si hay algún problema / ataque. 4 realmente una variación de 3: el usuario se autenticará en algún servicio de terceros y solo emitirá un token de acceso (temporal). Entonces, si la cuenta está comprometida, el token eventualmente caducará y / o será revocado (consulte OAuth). Considere los riesgos y la cantidad de trabajo a implementar y elija su opción.

En cuanto al uso de certificados de cliente, puede almacenarlos cifrados, por lo que debe proporcionar una frase de contraseña para usarlos. En pre-ICS, debe implementar esto usted mismo, en ICS puede usar el almacén de claves del sistema a través de la API KeyChain. Solo obtendrá acceso a la clave privada después de desbloquear el dispositivo (utiliza la contraseña / PIN de desbloqueo para proteger las claves) y el usuario otorga permiso explícitamente.

Si desea ceñirse a su forma actual de hacer las cosas, implemente la parte HMAC en código nativo (OpenSSL, etc.) y genere la clave en tiempo de ejecución combinando bits de ella. Eso dificultaría bastante la ingeniería inversa. Además, es posible que desee agregar algún tipo de nonce, para que las solicitudes no se puedan reproducir.

1
Nikolay Elenkov 23 abr. 2012 a las 06:23
Por lo tanto, parece que brindar una solución en algo más que ICS, la ruta que vamos a seguir es probablemente el camino a seguir. Me pregunto si hicimos algo en código nativo, pero tal vez hicimos algo contra el hash de la firma de firma. De esa forma, la clave real no se guarda, sino que la generan varias partes. (o haciendo algo como nonce + hash + algún algoritmo todo hecho en nativo). ¿Alguna idea de si las api del administrador de paquetes están disponibles en nativo? Supongo que no, tendría que escribirles una interfaz jni.
 – 
Chrispix
23 abr. 2012 a las 07:39
¿Qué estás intentando autenticar? ¿El usuario? ¿El dispositivo? ¿La transacción? Si es el dispositivo, puede derivar una clave de cualquier (o una combinación de) propiedades del dispositivo (IMEI, dirección MAC, etc.) No creo que haya un PackageManager nativo, pero no lo he comprobado realmente.
 – 
Nikolay Elenkov
23 abr. 2012 a las 07:43
Supongo que estoy tratando de autenticar al cliente (aplicación, no al teléfono) y al usuario.
 – 
Chrispix
23 abr. 2012 a las 22:17
Para autenticar la aplicación, podría funcionar hacer algo basado en el valor de la firma. Eso debería eliminar las aplicaciones reempaquetadas. Probablemente pueda obtener la firma usando zlib o similar para extraerla del APK. Aquí se presenta algo similar (para CRC): static.googleusercontent.com/external_content/untrusted_dlcp/…
 – 
Nikolay Elenkov
24 abr. 2012 a las 07:08
Revisaré zlib, eso debería ayudar. Gracias.
 – 
Chrispix
24 abr. 2012 a las 18:59