Как проверить установленное приложение во время выполнения, чтобы предотвратить фишинг-атаку?

У меня есть приложение для оплаты на моем устройстве, мое приложение подключается к сервису этого приложения, чтобы получить ожидающее намерение для запуска платежной активности, а затем прослушать результат в методе onActivityResult (). (Аналогично сценарию In-App-Purchase)

Я установил имя пакета для намерения платежа. Но вы знаете, это не гарантирует, что платежное приложение доверено. Если кто-то устанавливает поддельное приложение через неизвестный источник с тем же именем пакета и одной и той же поддержкой службы поддержки, то он может дать мне ожидающее намерения и фишинг моей информации о пользователе.

Я проверяю результат платежа с помощью какого-то механизма и что только безопасное мое приложение от результата поддельной оплаты, но мой пользователь приложения вводит свои данные в приложение phisher. (Этот параграф говорит, что моя проблема не является доверчивым ответом на платежное приложение, моя проблема – доверенное платежное приложение перед запуском их деятельности )

Я знаю какой-то подход, который я могу проверить подписи другого приложения и открытого ключа. Если ОС Android гарантирует, что открытый ключ и подпись доступны только для чтения и соответствуют установленному приложению , я могу положиться на это и проверить открытый ключ платежного приложения до отправки намерения на это. Но я думаю, что они не готовы и только для проверки соответствия В установке.

Любое предложение (аналогичный или другой подход) для предотвращения фишинговой атаки?

Обновлено : около 50% приложения для установки приложения с веб-сайта корпорации напрямую (Unknown-Source).

Android предлагает собственный метод проверки того, установлено ли приложение из Play Store, даже в App Store от Amazon. Но работает ли он над другими приложениями?

Взгляните на метод:

PackageManager.getInstallerPackageName(String packageName) (Документация)

К счастью для вас, getInstallerPackageName принимает имя пакета String, что означает, что вы можете передать ему идентификатор пакета вашего соседнего приложения и вернуть ему имя пакета, которое его установило!

В этом примере вы узнаете, установлено ли ваше соседнее приложение в Play Store, aka com.android.vending :

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

У магазина приложений Amazon есть нечетное имя пакета:

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

Это должно быть все, что вам нужно, надеюсь, что это поможет!

Что делать, если основное приложение получает подпись платежного приложения через диспетчер пакетов api и проверяет его (например, по whitlist подписи)? Процесс проверки также может произойти на главном сервере приложений.

EDIT: что-то вроде этого

  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"); } } 

Вы ищете комбинацию подписей и разрешений приложений. Чтобы прояснить это, это будет работать, только если вы владеете обоими приложениями и можете подписывать их одним и тем же ключом.

Согласно документам:

«Подпись»: разрешение, предоставляемое системой только в том случае, если запрашивающее приложение подписано с тем же сертификатом, что и приложение, объявившее разрешение. Если сертификаты совпадают, система автоматически предоставляет разрешение без уведомления пользователя или запроса на явное одобрение пользователя.

Это означает, что сама ОС Android предусматривает, что подписи двух приложений должны совпадать, чтобы разрешение было предоставлено. Это то, что вы хотите, поскольку разрешение не будет предоставлено, если кто-то попытается подделать ваше приложение. Поскольку они не могут подписывать свое приложение с вашим личным ключом, они не могут подделать вашу подпись.

Чтобы создать разрешение, в манифесте для приложения, предоставляющего услугу оплаты, вы должны объявить его следующим образом:

 <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" /> ... 

Затем, когда вы объявляете свое обслуживание, защитите его с помощью android:permission которое вы объявили:

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

Наконец, вы заявляете в своих клиентских приложениях, что вы используете это разрешение:

 <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> 

Пока оба приложения подписаны с одним и тем же ключом подписки, ОС предоставит разрешение. Для получения дополнительной информации посетите http://developer.android.com/guide/topics/security/permissions.html#defining и http://developer.android.com/guide/topics/manifest/permission-element.html.

Intereting Posts
Как безопасно хранить пароли на Android? Как изменить цвет текста центра ввода в Android DataBindingUtil.setContentView – параметр типа T имеет несовместимые верхние границы Android: autoLink для телефонных номеров не всегда работает Снимок экрана Android OpenGL Android Studio: как сгенерировать подписанный apk с помощью Gradle? Изменить Focus на EditText Android Android – NotificationCompat.Builder укладывает уведомления с помощью setGroup (group) не работает Android N Java 8 (компилятор Jack) и Kotlin interop Измерьте прошедшее время между двумя MotionEvents в Android Как искать данные в Firebase Android Непритязание вытяжного устройства для AngularApple () не работает на угловом webapp (appium / chrome на реальном устройстве) Как изменить имя списка Listview После отправки запроса сервера внутри пользовательского класса адаптера? Включение режима самолета через ADB (Android 4.1 или ранее) Недостаточно памяти при распределении байтов (битмап как строка для веб-сервиса с использованием мыла)