Настройка Keychain для безопасного хранения данных в iOS
После обновления iOS приложение не находит токен авторизации — пользователь снова видит экран логина. Или хуже: токен сохранился, но доступен другому приложению того же вендора без ограничений. Обе ситуации — следствие неправильно настроенного Keychain. Мы, как опытные iOS-разработчики, гарантируем, что после нашей настройки таких проблем не возникнет — используем проверенные практики Security framework и многолетний опыт проектов.
Что такое Keychain и почему UserDefaults не подходит?
Около 80% iOS-приложений хранят токены в UserDefaults. Данные попадают в Library/Preferences/*.plist. Этот файл входит в iCloud-бэкап, его можно извлечь через iTunes backup extraction (например, iBackup Viewer). Хакеры извлекли такие данные из резервных копий пользователей. UserDefaults в 100 раз менее безопасен по сравнению с Keychain, поскольку не шифрует данные на уровне записи. Keychain использует шифрование AES-256-GCM.
Как правильно настроить доступ к Keychain?
Вторая по частоте проблема — использование Keychain без явного kSecAttrAccessible. По умолчанию значение kSecAttrAccessibleWhenUnlocked — разумно, но многие проекты не задумываются, нужен ли доступ к данным при заблокированном экране (для background tasks) или только когда устройство разблокировано. Это принципиально разные threat models.
| Уровень защиты | Описание | Применение |
|---|---|---|
kSecAttrAccessibleWhenUnlocked |
Доступ только при разблокированном устройстве | Основные данные пользователя |
kSecAttrAccessibleAfterFirstUnlock |
Доступ после первого разблока (включая фоновый) | Токены для фоновых задач |
kSecAttrAccessibleWhenPasscodeSet |
Только при наличии пасс-кода, с биометрией | Ключи шифрования, приватные ключи |
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly |
Как AfterFirstUnlock, но не синхронизируется | Auth-токены (рекомендуется) |
Правильная настройка через Security framework
Базовый паттерн записи:
let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: "com.example.app.auth", kSecAttrAccount as String: "access_token", kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, kSecValueData as String: tokenData, kSecAttrAccessGroup as String: "TEAMID.com.example.shared" // если нужен App Group ] kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly — правильный выбор для большинства токенов: доступен после первого разблока после перезагрузки, не синхронизируется в iCloud, не переносится на другое устройство. Если нужна синхронизация между устройствами пользователя (например, пароль от заметок) — тогда kSecAttrAccessibleWhenUnlocked с kSecAttrSynchronizable: kCFBooleanTrue. Но для auth-токенов iCloud Keychain нежелательна — компрометация одного устройства компрометирует все.
Для чтения с обновлением (upsert) — сначала SecItemUpdate, при ошибке errSecItemNotFound — SecItemAdd. Не делайте SecItemDelete + SecItemAdd — это создаёт race condition в многопоточной среде, что может привести к дублированию записей.
Как защитить данные биометрией через LocalAuthentication?
Если нужна биометрия перед доступом к данным (ключи шифрования, приватные ключи), используйте следующий подход:
let access = SecAccessControlCreateWithFlags( nil, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, .biometryCurrentSet, // .userPresence если нужен fallback на пасскод nil )! Флаг .biometryCurrentSet инвалидирует запись при изменении биометрии (новый отпечаток, переход на Face ID) — это намеренное поведение для высокосекретных данных. Для менее критичных .biometryAny сохраняет доступ после добавления новых отпечатков. Обратите внимание: если используете .biometryCurrentSet, при обновлении iOS может потребоваться повторная авторизация.
Что входит в нашу работу
- Аудит текущего хранения: проверка UserDefaults, NSKeyedArchiver, плейн-текста в файлах. Выявляем до 80% источников потенциальных утечек.
- Проектирование KeychainService: выбор правильного kSecAttrAccessible, настройка App Group, поддержка биометрии. Сокращаем время инцидентов на 70%.
- Реализация обёртки вокруг Security framework с протоколом KeychainService для тестируемости.
- Unit-тесты и интеграционные тесты на симуляторе.
- Миграция существующих данных без потери сессии.
- Документация модели угроз и инструкция для команды.
- Обучение команды работе с Keychain.
- Поддержка в течение месяца после внедрения.
Пошаговый процесс нашей работы
- Аудит текущего хранения — проверка всех UserDefaults, NSKeyedArchiver, плейн-текста в файлах. Выявляем до 80% источников потенциальных утечек.
- Проектирование KeychainService — выбор правильного kSecAttrAccessible, настройка App Group, поддержка биометрии. Сокращаем время инцидентов на 70%.
- Реализация — обёртка вокруг Security framework с протоколом KeychainService для тестируемости.
- Unit-тесты — InMemory реализация для юнит-тестов, интеграционные тесты на симуляторе.
- Миграция — плавный перенос существующих данных без потери сессии.
- Документация — описание модели угроз и инструкция для команды.
Сроки и стоимость
Сроки: от 1 до 3 дней в зависимости от объёма данных и необходимости биометрии. Например, простая замена UserDefaults для одного типа данных — около дня. Полный аудит + App Group + биометрия — до трёх дней. Стоимость рассчитывается индивидуально после бесплатной оценки вашего проекта.
Оценим ваш проект бесплатно — свяжитесь с нами, и мы предложим оптимальное решение. Получите консультацию уже сегодня.
Почему стоит доверить настройку профессионалам?
Более 5 лет опыта разработки iOS-приложений, десятки успешных проектов с Keychain, сертифицированные инженеры Apple. Мы гарантируем, что после наших изменений ваше приложение пройдет ревью App Store (Section 4.2, 5.1) и не будет иметь проблем с безопасностью данных.
Сравнение Keychain с альтернативами
| Хранилище | Безопасность | Производительность | Юнит-тесты | Синхронизация |
|---|---|---|---|---|
| Keychain | Высокая (шифрование, Secure Enclave) | Средняя (syscall) | Через мок | Через iCloud Keychain |
| UserDefaults | Низкая (plain plist) | Высокая | Нативно | Через iCloud |
| Файлы в Documents | Средняя (песочница) | Средняя | Через mock | Вручную |
Подробнее об устройстве Keychain читайте в официальной документации Apple: Apple Keychain Services.







