¿Cómo verificar la aplicación instalada en tiempo de ejecución para evitar el ataque de phishing?

Tengo una aplicación de pago en mi dispositivo, mi aplicación se conecta al servicio de esa aplicación para obtener una intención pendiente para la actividad de pago de lanzamiento y, a continuación, escuche el resultado en el método onActivityResult () (similar al escenario In-App-Purchase)

Puse el nombre del paquete para la intención del pago. Pero usted sabe, no es garantía de que la aplicación de pago es de confianza. Si alguien instala una aplicación falsa a través de una fuente desconocida con el mismo nombre de paquete y la misma implementación de service-service, entonces puede darme intención pendiente y phishing mi información de usuario.

Verifico el resultado del pago con algún mecanismo y que sólo mi aplicación segura de resultado de pago falso, pero mi usuario de la aplicación introducir sus datos en la aplicación phisher. (Este párrafo dice que mi problema no es confiar en la respuesta de la aplicación de pago, mi problema es la aplicación de pago de confianza antes de lanzar su actividad )

Conozco un enfoque que puedo comprobar la firma de otra aplicación y la clave pública. Si el sistema operativo Android garantiza que la clave pública y la firma son de sólo lectura y coinciden con la aplicación instalada , puedo confiar en ello y comprobar la clave pública de la aplicación de pago antes de enviar la intención de that.but supongo que no está lista y sólo coinciden En la instalación.

Cualquier sugerencia (enfoque similar o diferente) para prevenir el ataque de phishing?

Actualizado : Aproximadamente el 50% de la aplicación de instalación de aplicaciones del sitio web de mi empresa directamente (Unknown-Source).

Android ofrece un método nativo para verificar si una aplicación se ha instalado desde Play Store, incluso Amazon App Store. ¿Pero funciona en otras aplicaciones?

Echa un vistazo al método:

PackageManager.getInstallerPackageName(String packageName) (Documentación)

Afortunadamente para usted, getInstallerPackageName acepta un nombre de paquete de cadena, lo que significa que puede alimentar el ID de paquete de su vecino-aplicación y que devuelva el nombre del paquete que lo instaló.

Este ejemplo le dirá si su aplicación vecina fue instalada por Play Store, también conocido como com.android.vending :

 if(context.getPackageManager().getInstallerPackageName("com.untrusted.app") == "com.android.vending") { // ^^^ CHANGE ^^^ //Verified; app installed directly from Play Store } 

La tienda de aplicaciones de Amazon tiene un nombre de paquete extraño:

 if(context.getPackageManager().getInstallerPackageName("com.untrusted.app") == "com.amazon.venezia") { //Verified; app installed directly from Amazon App Store } 

Esto debe ser todo lo que necesita, espero que ayude!

¿Qué pasa si la aplicación principal obtiene la firma de la aplicación de pago a través de la API del gestor de paquetes y la valida (por ejemplo, una lista de firmas)? El proceso de validación también puede ocurrir en el servidor principal de aplicaciones.

EDIT: algo así

  List<byte[]> whitelist = ... ; // load from config or something... PackageManager pm = this.getPackageManager(); String packageName = "payment.app.package.name"; PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); Signature[] signatures = packageInfo.signatures; for (Signature sig : signatures) { InputStream input = new ByteArrayInputStream(sig.toByteArray()); CertificateFactory cf = CertificateFactory.getInstance("X509"); X509Certificate cert = (X509Certificate) cf.generateCertificate(input); PublicKey pb = cert.getPublicKey(); if (! whitelist.contains(pb.getEncoded())) { throw new Exception("public key is not valid"); } } 

Lo que está buscando es una combinación de firmas de aplicación y permisos. Para aclarar, esto sólo funcionará si posee ambas aplicaciones y puede firmarlas con la misma clave.

Según los documentos:

"Signature": Un permiso que el sistema otorga sólo si la aplicación solicitante está firmada con el mismo certificado que la aplicación que declaró el permiso. Si los certificados coinciden, el sistema concede automáticamente el permiso sin notificar al usuario o solicitar la aprobación explícita del usuario.

Esto significa que el propio sistema operativo Android exige que las firmas de las dos aplicaciones deben coincidir para que el permiso se conceda. Esto es lo que desea, ya que el permiso no se concederá si alguien intenta falsificar su aplicación. Dado que no pueden firmar su aplicación con su clave privada, no hay manera de que puedan forjar su firma.

Para crear un permiso, en su Manifiesto para la aplicación que proporciona el servicio de pago, debe declararlo así:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp.paymentservice" > <permission android:name="com.example.myapp.paymentservice.permission.PAYMENT" android:label="@string/permission_payment_label" android:description="@string/permission_payment_description" android:protectionLevel="signature" /> ... 

Luego, al declarar su servicio, protéjalo con el android:permission que declaró:

  ... <service android:name=".BillingService" android:permission="com.example.myapp.paymentservice.permission.PAYMENT" /> </manifest> 

Finalmente, declara en su aplicación de cliente (s) que utiliza ese permiso:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp.clientapp" > <uses-permission android:name="com.example.myapp.paymentservice.permission.PAYMENT" /> ... </manifest> 

Siempre y cuando las dos aplicaciones estén firmadas con la misma clave de firma, el sistema operativo concederá el permiso. Para obtener más información, consulte http://developer.android.com/guide/topics/security/permissions.html#defining y http://developer.android.com/guide/topics/manifest/permission-element.html

  • DevicePolicyManager wipeData no borrar la configuración de correo electrónico
  • ¿Dónde almacenar la información global sensible, como las claves API en la aplicación de Android?
  • Almacenamiento de clave secreta en KeyStore sin el parámetro ProtectionParameter
  • Java.lang.SecurityException: Permiso Denial: Intención inicial {act = android.intent.action.MAIN cat =
  • Biblioteca a recursos de cifrado y descifrado
  • Android.security.KeyStoreException: Bloc de clave no válido
  • AndroidKeyStore eliminado después del cambio de contraseña del dispositivo
  • Uso de software / hardware con respaldo Android Keystore y posibles desventajas de seguridad / usabilidad
  • Almacenamiento de claves en Android
  • ¿Por qué no conectar android a la base de datos directamente?
  • ¿Cómo mantener seguro el secreto del consumidor de OAuth y cómo reaccionar cuando está comprometido?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.