Следующая новость
Предыдущая новость

Android: взламываем Medium и защищаем данные приложения

25.09.2020 13:22
Android: взламываем Medium и защищаем данные приложения

Содержание статьи

  • Почитать
  • Взлом приложения Medium
  • Разработчику
  • Защищаем данные приложения правильно
  • Знакомимся с Jetpack DataStore
  • Делаем приложение устойчивым к обрыву соединения
  • Используем делегирование в Kotlin
  • Функции-расширения для работы со строками
  • Еще немного функций-расширений
  • Неизвестные инструменты разработки
  • Библиотеки

Сегодня в выпуске: взламываем приложение Medium, защищаем данные приложения, знакомимся с Jetpack DataStore, делаем приложение устойчивым к обрыву соединения и используем делегирование в Kotlin. А также: подборка функций-расширений на все случаи жизни, неизвестные инструменты разработчика и новые библиотеки.

Почитать

Взлом приложения Medium

Reverse Engineering The Medium App (and making all stories in it free) — статья о том, как взломать официальное приложение Medium и сделать все посты бесплатными.

Medium дает новым пользователям возможность прочитать три поста бесплатно. Для трекинга новых пользователей используются куки: если куки с определенным ключом не установлены — значит, пользователь новый, иначе пользователь старый. Заходя на Medium в приватном режиме (который стирает все куки), пользователь всегда будет новым и сможет читать статьи сколько угодно.

Приложение Medium для Android использует ровно тот же механизм для отслеживания новых пользователей. Но вместо приватного режима здесь придется использовать другой подход. Приложение необходимо декомпилировать с помощью Apktool, а затем внести изменение, которое будет забывать о любых куках при обращении к адресу api.medium.com/_/api/posts/{postId}.

Сделать это можно, внеся правки в класс JavaNetCookieJar библиотеки OkHTTPClient, которую использует приложение Medium.

Однако изменить дизассемблированное приложение можно, только переписав этот код на языке Smali:

invoke-virtual {v2}, Ljava/net/URI;->toString()Ljava/lang/String; move-result-object v9 const-string v6, "^https:\/\/api.medium.com\/_\/api\/posts\/[^\/]+[?](.)*$" invoke-virtual {v9, v6}, Ljava/lang/String;->matches(Ljava/lang/String;)Z move-result v7 if-nez v7, :cond_4 

Нужно вставить этот код в дизассемблированный листинг того же класса JavaNetCookieJar, а затем собрать приложение, используя Apktool.

Разработчику

Защищаем данные приложения правильно

Modern Android Security Development — статья с советами, как правильно реализовать шифрование и защиту данных в приложении.

Используй библиотеку Jetpack Security

Если определенные данные приложения (ключи API, пароли, личная информация) должны быть зашифрованы, не полагайся на советы со Stack Overflow и статьи пятилетней давности. В 2020 году твой выбор — Jetpack Security.

Эта библиотека позволит сгенерировать мастер-ключ и зашифровать данные максимально просто и максимально корректным и безопасным образом. Jetpack Security базируется на библиотеке Google Tink, хранит мастер-ключи в защищенном аппаратном хранилище (KeyStore) и позволяет шифровать как файлы, так и настройки приложения. Пример создания мастер-ключа AES в защищенном хранилище:

fun generateMasterKey(context: Context): MasterKey {     return MasterKey.Builder(context)         .setKeyGenParameterSpec(AES256_GCM_SPEC)         .build() } 

Используй SealedObject для сохранения или передачи объектов

Если тебе необходимо сохранить в постоянной памяти объект — используй класс SealedObject из стандартной библиотеки Java. Он позволяет создать зашифрованную сериализуемую версию объекта (обернуть его) так, чтобы его можно было безопасно хранить в незащищенном хранилище. Следующий класс представляет реализацию шифрования объектов с помощью SealedObject:

class ObjectEncryptor {     private val scheme: String = "AES / CBC / PKCS7Pdding / Whatever..."     private val cipher: Cipher by lazy { Cipher.getInstance(scheme) }      fun sealObject(`object`: Serializable, privateKey: String): Serializable {         val secretKey = SecretKeySpec(privateKey.toByteArray(), scheme)         cipher.init(ENCRYPT_MODE, secretKey)          return SealedObject(`object`, cipher)     }      @Throws(IOException::class)     fun unsealObject(`object`: Serializable, privateKey: String): Serializable {         val secretKey = SecretKeySpec(privateKey.toByteArray(), scheme)         val sealedObject = `object` as SealedObject          return sealedObject.getObject(secretKey) as Serializable     } } 

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

1 год

7690 р.

1 месяц

720 р.

Я уже участник «Xakep.ru»

Источник

Последние новости