‹ назад в библиотеку

Android Security Measures - Jitendra Purohit

Автор: Jitendra Purohit

Автор перевода: В.Е. Лебедев

Источник: Android Security Measures – Pen | Bold Kiln Press – Medium



Если вы создаете приложение или имеете готовое приложение, скорее всего, вам часто приходится задумываться о том, как защитить свое приложение, свои данные и данные вашего клиента.

Необходимо потратить немало времени для того, чтобы заработали все части мобильного приложения: программный код, бизнес-логика на внутренней сети и на стороне клиента, базы данных, API-интерфейсы, перенаправляющие данные между ними, устройством и его операционной системой, и пользователем. Каждый из них играет важную роль в обеспечении безопасности приложения. Для компаний с мобильными приложениями на переполненном конкурентном рынке надежная защита может иметь огромное значение. Вот несколько советов, которые вы должны принять во внимание при работе над безопасностью мобильного приложения:


1. Разрешение на основе подписи

Для чего: Оно проверяет, что приложение, обращающееся к данным, подписано с помощью оригинального ключа подписи.

Реализация:


<manifest xmlns:android=”http://schemas.android.com/apk/res/android" package=”com.example.myapp”>
  <permission android:name=”android.permission.INTERNET” android:protectionLevel="signature" />


2. Использовать SSL трафик

Для чего: Используется для установления зашифрованной связи между сервером и клиентом.

Реализация: Если ваше приложение обменивается данными с веб-сервером, который имеет сертификат, выданный известным, доверенным центром сертификации, вы можете использовать этот запрос HTTPS.


URL url = new URL(“https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream();


3. Добавить конфигурацию безопасности сети

Для чего: Используется для установления безопасного соединения между сервером и клиентом.

Реализация:

Для Android N и выше


a. Объявите конфигурацию в манифесте вашего приложения.


<manifest>
  <application android:networkSecurityConfig=”@xml/network_security_config”>
  </application>
</manifest>


b. Добавьте файл ресурсов XML, расположенный по адресу res/xml/network_security_config.xml.


<network-security-config> <domain-config cleartextTrafficPermitted=”false”>
  <domain includeSubdomains="true">appmattus.com</domain>
    <pin-set>
      <pin digest="SHA-256">4hw5tz+scE+TW+mlai5YipDfFWn1dqvfLG+nU7tq1V8=</pin>
      <pin digest="SHA-256">YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=</pin>
    </pin-set>
  </domain-config>
</network-security-config>

Для Android N и выше, ниже Android N


Чтобы получить открытые ключи с доменным именем, приведенный ниже код распечатывает открытые ключи в цепочке в виде хэша SHA-256 с использованием кодировки base 64.


openssl s_client -showcerts -connect domain.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM >mycertfile.pem


Теперь запустите эту команду, чтобы получить ключ.


CertificatePinner certPinner = new CertificatePinner.Builder()
    .add("domain.com",
      "sha256/4hw5tz+scE+TW+mlai5YipDfFWn1dqvfLG+nU7tq1V8=")
    .build();

OkHttpClient okHttpClient = new OkHttpClient.Builder()
    .certificatePinner(certPinner)
    .build();


Используя Retrofit, так как Retrofit построен на основе OkHttp, настроить его для закрепления так же просто, как настроить OkHttpClient, как показано выше, и передать его в свой Retrofit.Builder.


Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://domain.com")
    .addConverterFactory(GsonConverterFactory.create())
    .client(okHttpClient)
    .build();


4. Используйте алгоритм шифрования, такой как AES, для сохранения учетных данных

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

Реализация:


a. Создайте подписанный ключ.


public static SecretKey generateKey()
{
  return secret = new SecretKeySpec(password.getBytes(), “AES”);
}


b. Зашифруйте сообщение и получите зашифрованный массив байт.


public static byte[] encryptMsg(String message, SecretKey secret)
{
  Cipher cipher = null;
  cipher = Cipher.getInstance(“AES/ECB/PKCS5Padding”);
  cipher.init(Cipher.ENCRYPT_MODE, secret);
  byte[] cipherText = cipher.doFinal(message.getBytes(“UTF-8”));
  return cipherText;
}


c. Расшифруйте массив байт и верните исходное сообщение.


public static String decryptMsg(byte[] cipherText, SecretKey secret)
{
  Cipher cipher = null;
  cipher = Cipher.getInstance(“AES/ECB/PKCS5Padding”);
  cipher.init(Cipher.DECRYPT_MODE, secret);
  String decryptString = new String(cipher.doFinal(cipherText), “UTF-8”);
  return decryptString;
}


5. Использовать шифрование БД SQL

Для чего: Повышает безопасность данных SQLite.

Реализация:


a. Добавить зависимость в файле Gradle.


implementation ‘net.zetetic:android-database-sqlcipher:3.5.9@aar’


b. Вызовите InitializeSQLCipher() из onCreate.


private void InitializeSQLCipher() {
  SQLiteDatabase.loadLibs(this);
  File databaseFile = getDatabasePath(“database.db”);
  databaseFile.mkdirs();
  databaseFile.delete();
  SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(file, “test”, null);
  database.execSQL(“create table t1(a, b)”);
  database.execSQL(“insert into t1(a, b) values(?, ?)”, new Object[]{“parameter 1”, “parameter 2”});
}


6. Защита доступа к контент-провайдеру приложения

Для чего: Запретить другим приложениям доступ к данным вашего приложения.

Реализация:


<provider
  android:name=”android.support.v4.content.FileProvider”
  android:authorities=”com.example.myapp.fileprovider”
  // это предотвратит доступ других приложений к данным ваших приложений
  android:exported=”false”>
</provider>


7. Обфускация

Для чего: Обфускация вашего приложения очень затрудняет реверс-инжиниринг приложения.

Реализация:



buildTypes {
  release {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  }
}


8. Используйте Dexguard (более мощный инструмент Proguard)

Для чего: DexGuard обеспечивает расширенную защиту для приложений Android.


9. Запретить установку на рутированных устройствах

Для чего: Пользователь с правами админимтратора может получить доступ к системным каталогам любого приложения. Это можетт быть серьезной проблемой безопасности.

Реализация: Если isDeviceRooted () возвращает true. Запретить пользователю использовать приложение.


public class RootUtil {
  public static boolean isDeviceRooted() {
    return checkRootMethod1() || checkRootMethod2() || checkRootMethod3();
  }

  private static boolean checkRootMethod1() {
    String buildTags = android.os.Build.TAGS;
    return buildTags != null && buildTags.contains(“test-keys”);
  }

  private static boolean checkRootMethod2() {
    String[] paths = { “/system/app/Superuser.apk”, “/sbin/su”, “/system/bin/su”, “/system/xbin/su”, “/data/local/xbin/su”, “/data/local/bin/su”, “/system/sd/xbin/su”, “/system/bin/failsafe/su”, “/data/local/su”, “/su/bin/su”};
    for (String path : paths) {
      if (new File(path).exists()) return true;
    }
    return false;
  }

  private static boolean checkRootMethod3() {
    Process process = null;
    try {
      process = Runtime.getRuntime().exec(new String[] { “/system/xbin/which”, “su” });
      BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
      if (in.readLine() != null) return true;
      return false;
    } catch (Throwable t) {
      return false;
    } finally {
      if (process != null) process.destroy();
    }
  }
}



Мобильные устройства пользователей это место, где скрываются хакеры, пытаясь украсть конфиденциальную информацию и поставить под угрозу безопасность приложения. Благодаря надежной стратегии обеспечения безопасности приложений и опыту мобильного разработчика, который поможет вам быстро реагировать на угрозы и ошибки, ваше приложение станет намного более защищенным и безопасным для пользователей. А также обеспечит их лояльность (и ваши активы) в будущем.