Мобильная разработка

Mobile Security

2021 год. Исследователи находят в популярном банковском приложении Firebase API-ключ прямо в коде. Ключ имел доступ к базе данных 3 миллионов пользователей. Приложение не было взломано - его просто внимательно прочитали.

  • **Финтех** - Keychain/Keystore для хранения биометрических токенов: ни один из банков уровня Тинькофф или Сбера не хранит токены в UserDefaults
  • **Certificate pinning** - обязателен для приложений с финансовыми операциями: Charles Proxy на корпоративном Wi-Fi без pinning = полный доступ к API
  • **Обфускация + R8** - Uber, Airbnb, Booking скрывают алгоритмы ценообразования и антифрод-логику от конкурентов через aggressive ProGuard

Keychain: зашифрованное хранилище iOS

iOS Keychain - единственное место, где нужно хранить чувствительные данные: токены, пароли, ключи. Это не файл и не база данных в привычном смысле. Это сервис операционной системы с собственным шифрованием на уровне Secure Enclave.

UserDefaults хранит данные в незашифрованном plist. Documents/Library хранятся в открытом виде и доступны через iTunes Backup без jailbreak. Keychain шифруется ключом, привязанным к Secure Enclave - даже при извлечении из устройства расшифровать нельзя.

Атрибут `kSecAttrAccessible` критичен: `WhenUnlockedThisDeviceOnly` - лучший выбор для sensitive data (не переходит в iCloud Backup, недоступен без разблокировки). Значение `Always` - антипаттерн: данные читаются даже при заблокированном устройстве.

Почему нельзя хранить токены в UserDefaults?

Android Keystore: аппаратная безопасность

Android Keystore System - аналог iOS Keychain, но с важным нюансом: ключи генерируются и хранятся в аппаратном безопасном элементе (StrongBox на современных устройствах). Ключ никогда не покидает TEE (Trusted Execution Environment). Его нельзя экспортировать - только использовать для операций.

SharedPreferences имеет ту же проблему, что UserDefaults: незашифрованный XML. EncryptedSharedPreferences из Jetpack Security - правильный выбор: он прозрачно шифрует через Keystore, но API остаётся привычным. Внутри - AES256-GCM для значений и AES256-SIV для ключей.

StrongBox (TEE с отдельным CPU) доступен не на всех устройствах. `setIsStrongBoxBacked(true)` с `isStrongBoxSupported()` проверкой - лучшая практика. На устройствах без StrongBox Keystore откатывается к software-based implementation.

Что означает, что ключ хранится в Android Keystore с StrongBox?

Certificate Pinning: защита от MITM

Certificate pinning - техника, при которой приложение отказывается соединяться, если сертификат сервера не совпадает с ожидаемым. Стандартная цепочка доверия TLS доверяет любому CA из системного хранилища. Pinning говорит: "только этот конкретный сертификат или ключ".

Без pinning атака Charles Proxy / mitmproxy тривиальна: установить корневой CA прокси в систему - и весь трафик приложения видно в открытом виде. Именно так исследователи анализируют private API крупных приложений.

Пинить публичный ключ (SPKI) предпочтительнее, чем сам сертификат: ключ не меняется при обновлении сертификата. Всегда храни backup pin - на случай смены ключа у сервера. Без backup pin неверный пин = приложение мёртво до следующего релиза.

Почему пинить публичный ключ (SPKI) лучше, чем пинить сам сертификат?

Обфускация и защита от реверс-инжиниринга

APK можно декомпилировать за 30 секунд. IPA сложнее, но тоже не является защитой. Любой код, попавший на устройство пользователя, можно прочитать. Обфускация не делает код нечитаемым - она повышает стоимость анализа.

На Android стандарт - R8/ProGuard. Переименовывает классы, методы и поля в однобуквенные идентификаторы. Удаляет неиспользуемый код. Логика остаётся, но читать `a.b.c()` вместо `PaymentManager.processCard()` значительно сложнее.

Обфускация не заменяет правильную архитектуру безопасности. API-ключи, захардкоженные в коде, будут найдены даже в обфусцированном APK через strings анализ. Секреты должны жить на сервере, а не в приложении. Обфускация защищает бизнес-логику, не credentials.

Обфускация делает мобильное приложение невозможным для взлома

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

Любой код, попавший на устройство пользователя, можно проанализировать при достаточном времени. Настоящая безопасность строится через правильную архитектуру: секреты на сервере, минимальные привилегии, certificate pinning - а не через сокрытие кода

Что обфускация с ProGuard/R8 НЕ защищает?

Связанные темы

Мобильная безопасность пересекается с криптографией, сетевой безопасностью и OWASP:

  • Криптография: симметричная и асимметричная — AES-GCM под Keychain, RSA/EC в certificate pinning
  • TLS/SSL и PKI — Certificate pinning расширяет модель доверия PKI
  • Безопасность мобильных приложений — Полный OWASP Mobile Top 10 курс

Ключевые идеи

  • **Keychain (iOS) и Keystore (Android)** - единственное место для токенов и ключей; UserDefaults/SharedPreferences - антипаттерн
  • **Certificate pinning** блокирует MITM-атаки через прокси; пинить публичный ключ надёжнее, чем сам сертификат
  • **Обфускация** (R8/ProGuard) защищает бизнес-логику, но не скрывает строковые константы - секреты должны жить на сервере
  • **StrongBox** на Android и **Secure Enclave** на iOS обеспечивают аппаратную изоляцию ключей от основного CPU

Вопросы для размышления

  • Что произойдёт с приложением, если certificate pinning сработает против собственного обновлённого сертификата сервера?
  • Где граница между разумной обфускацией и overengineering в контексте мобильной безопасности?
  • Как биометрическая аутентификация (FaceID/TouchID) взаимодействует с Keychain и когда её стоит требовать?

Связанные уроки

  • mob-15 — Безопасное хранение push-токенов в Keychain - применение этого урока
  • sec-04 — Симметричная и асимметричная криптография лежит под Keychain/Keystore
  • sec-11 — TLS/PKI - основа certificate pinning
  • sec-09 — OWASP Mobile Top 10 расширяет веб-OWASP для мобильной специфики
  • sec-20 — Этот урок - база для полного курса по безопасности мобильных
  • sec-01
Mobile Security

0

1

Войти