Как проверить сертификат подписи APK на стороне клиента? - PullRequest
0 голосов
/ 08 января 2019

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

Поскольку подпись измененного приложения отличается от оригинальной подписи, я решил:

  1. Извлечение сертификата подписи, который встроен в приложение для Android
  2. отправить его на сервер с запросом на вход в систему (кодирование всего процесса проверки на стороне клиента (т. Е. Apk) не работает, поскольку кто-то может изменить apk, чтобы обойти его.)
  3. проверить это
  4. если сертификат действителен, запрос на вход в систему / в противном случае возвращает ошибку

Это мой код для номера 1 выше:

Context context = this;
PackageManager pm = context.getPackageManager();
String packageName = context.getPackageName();
int flags = PackageManager.GET_SIGNATURES;
PackageInfo packageInfo = null;

try {
    packageInfo = pm.getPackageInfo(packageName, flags);
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}

Signature[] signatures = packageInfo.signatures;  

Итак, мои вопросы:

  1. Есть ли лучший способ проверить apk?
  2. Если этот метод в порядке,
    2.1 Будет ли отправка сертификата высокой пропускной способностью?
    2.2 Как я могу проверить сертификат? (У меня есть mykey.jks на стороне сервера, который я изначально использовал для подписи apk)

(Кроме того, это мой первый вопрос о stackoverflow, поэтому указание на любые ошибки, которые я допустил при задании этого вопроса, высоко ценится !.)

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Как уже указывал @Pierre, способ, которым вы выполняете проверку, является действительным, но я хотел бы предупредить о том факте, что закрепление сертификата может быть обойдено во время выполнения, с такими инструментальными средами, как Frida или xPposed , но все же рекомендуется и рекомендуется использовать его как еще один уровень безопасности. Для получения более подробной информации об этом, пожалуйста, прочитайте эту статью , чтобы понять, как пиннинг легко реализовать, как это может быть кошмаром для поддержания с эксплуатационной точки зрения и как его можно обойти.

Есть ли лучший способ проверить apk?

Да, он существует и называется Аттестацией мобильных приложений. Это решение будет состоять из SDK, интегрированного в мобильное приложение, которое взаимодействует с облачным сервисом в фоновом режиме, что не влияет на работу пользователя.

Решение Mobile App Attestation гарантирует во время выполнения, что приложение не подвергается атаке человека посередине, подделывается, не работает на рутированном или поврежденном устройстве, не подключено к отладчику, не работает на эмуляторе и это тот же самый оригинал, загруженный в магазин приложений или магазин Google Play.

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

Когда секретное приложение, используемое службой облачной аттестации, не известно мобильному приложению, невозможно выполнить обратный инжиниринг токена JWT, даже если мобильное приложение подделано, работает на корневом устройстве или осуществляет связь через соединение, которое является быть целью человека в средней атаке.

Вы можете найти такой сервис в Approov (я работаю здесь), в котором есть SDK для нескольких платформ, включая Android. Для интеграции также потребуется небольшая проверка кода сервера API для проверки токена JWT.

Фрида

Динамический инструментарий инструментария для разработчиков, реверс-инженеров и исследователей безопасности.

Экспоузд

Xposed - это фреймворк для модулей, которые могут изменять поведение системы и приложений, не касаясь каких-либо APK.

токен JWT

Аутентификация на основе токена

JSON Web Tokens - это открытый промышленный стандарт RFC 7519 для безопасного представления заявок между двумя сторонами.

0 голосов
/ 08 января 2019

Прежде всего, кто-то всегда сможет обойти этот тип безопасности, например, путем жесткого кодирования сертификатов, передаваемых на ваш сервер. Вы можете только попытаться сделать это как можно сложнее, но это никогда не будет на 100% безопасно.

То, что ты говоришь, похоже, нормально. Обратите внимание, что pm.signatures не рекомендуется в пользу pm.signingInfo в последнем SDK.

Размер по размеру, сертификат не большой, но чтобы сделать запросы еще меньше, вам, вероятно, следует отправлять только хэш (например, SHA256).

Чтобы люди не могли жестко закодировать сертификат в запросе, вы также можете рассмотреть возможность хеширования другого значения вместе с сертификатом, например, хеш (сертификат + метка времени), и отправить также метку времени в запросе, чтобы вы могли пересчитать хеш-серверную часть. , И если отметка времени слишком далека от текущей даты, отклоните запрос. Опять же, это не совсем безопасно, но добавляет еще один уровень сложности для обратного проектирования вашего кода. Вы также можете добавить versionCode и начать отклонять запросы старых версий (например, если вы обнаружите ошибку безопасности в одной из ваших старых версий) и предлагать этим пользователям обновить приложение (или делать это для них в фоновом режиме и запрашивать только установить, благодаря новому API Play обеспечивает).

Как кто-то указал, ваш код также может проверить, что установка была произведена из Play (packageManager.getInstallerPackageName(getPackageName()).equals("com.android.vending");), но эта информация легко подделывается, поэтому не уверен, что она добавляет много безопасности.

Надеюсь, это поможет,

...