Keychain — ключевые понятия, архитектура и как работает

Автор: IT Sectr Опубликовано: 2026-03-14 Время чтения: 10 мин

Keychain — это защищённое хранилище учётных данных в iOS, watchOS, macOS и tvOS, которое управляет паролями, ключами и сертификатами на аппаратном уровне. В отличие от UserDefaults, данные в Keychain шифруются и изолируются по песочнице приложения. По данным Apple Developer Documentation, Keychain использует механизмы Secure Enclave и аппаратное шифрование AES-256 для защиты конфиденциальной информации.

Главное

  • Keychain — системное хранилище iOS для паролей, ключей и сертификатов с аппаратным шифрованием
  • Security framework предоставляет C-функции SecItemAdd, SecItemCopyMatching и SecItemDelete для работы с Keychain
  • Доступ к Keychain ограничен песочницей приложения, но возможен общий доступ через keychain access groups
  • Атрибут kSecAttrAccessible определяет уровень защиты: от Always до WhenUnlockedThisDeviceOnly
  • Keychain поддерживает хранение паролей, симметричных и асимметричных ключей, сертификатов X.509

Что такое Keychain?

Keychain — это защищённая база данных операционной системы Apple, предназначенная для безопасного хранения паролей, криптографических ключей, сертификатов и других конфиденциальных данных. Впервые Keychain появился в Mac OS 8.6 в 1999 году, а на iOS — с самой первой версии SDK.

Определение и назначение

Keychain решает фундаментальную проблему мобильной разработки: хранение секретов (токенов, паролей, ключей шифрования) в незащищённой файловой системе. В отличие от UserDefaults или SQLite, данные в Keychain хранятся в зашифрованном виде и автоматически шифруются при записи на диск.

Каждое приложение iOS работает в изолированной песочнице и имеет доступ только к своему keychain. Однако разработчик может настроить общий доступ к Keychain между приложениями одного разработчика через keychain access groups. Пользователь iCloud Keychain дополнительно синхронизирует данные между устройствами через сквозное шифрование.

По данным Apple Security White Paper (2025), Keychain использует аппаратное шифрование AES-256 с ключом, привязанным к уникальному идентификатору устройства (UID), что делает данные недоступными при извлечении из устройства.

Как работает Keychain на iOS?

Keychain функционирует как сервис уровней: приложение обращается к Security framework, который взаимодействует с демоном securityd, управляющим зашифрованной SQLite-базой Keychain. Каждая запись шифруется отдельным ключом, а сами ключи защищены аппаратным модулем Secure Enclave на устройствах с чипом A7 и новее.

Архитектура Security framework

Security framework предоставляет C-интерфейс для работы с Keychain Services. Основные функции: SecItemAdd (добавление), SecItemCopyMatching (поиск), SecItemUpdate (обновление) и SecItemDelete (удаление). Каждая операция принимает словарь атрибутов CFDictionaryRef, описывающий тип запроса.

Данные классифицируются по классам: kSecClassGenericPassword (произвольный пароль), kSecClassInternetPassword (пароль к интернет-сервису), kSecClassCertificate (сертификат), kSecClassKey (криптографический ключ) и kSecClassIdentity (связка ключа и сертификата).

Процесс сохранения данных

При сохранении пароля приложение формирует словарь с атрибутами: сервис, учётная запись, уровень доступа, метка. Security framework передаёт данные демону securityd, который шифрует запись ключом, привязанным к устройству, и сохраняет в Keychain SQLite. Извлечение происходит аналогично: запрос по атрибутам, поиск, расшифровка и возврат данных.

Важная особенность: при удалении приложения iOS автоматически очищает Keychain записи, созданные этим приложением (с iOS 10.3+). При переустановке приложения Keychain-данные предыдущей инсталляции недоступны, если не использовался iCloud Keychain.

swift
import Security

func savePassword(service: String, account: String, password: Data) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account,
        kSecValueData as String: password,
        kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
    ]
    SecItemAdd(query as CFDictionary, nil)
}

Типы данных в Keychain

Keychain поддерживает пять основных классов данных, каждый из которых имеет свой набор атрибутов и область применения. От выбора класса зависит, какие ключи поиска доступны и как данные шифруются.

Пароли и учётные записи

Классы kSecClassGenericPassword и kSecClassInternetPassword предназначены для хранения строковых паролей. Internet-версия дополнительно хранит данные сервера: домен, протокол, порт и путь аутентификации. GenericPassword используется для хранения любых паролей без привязки к серверу.

При сохранении интернет-пароля можно указать kSecAttrServer (домен), kSecAttrProtocol (HTTPS, FTP и т.д.), kSecAttrPort и kSecAttrPath. Это позволяет точно идентифицировать запись при автоматическом заполнении через AutoFill.

Криптографические ключи и сертификаты

Класс kSecClassKey хранит симметричные (AES) и асимметричные (RSA, EC) ключи. Класс kSecClassCertificate — сертификаты X.509. Класс kSecClassIdentity объединяет закрытый ключ и соответствующий сертификат в одну запись.

Для асимметричных ключей Keychain поддерживает атрибуты: kSecAttrKeyType (RSA, EC), kSecAttrKeySizeInBits (2048, 256), kSecAttrIsPermanent (сохранять ли в Keychain). Для сертификатов: kSecAttrLabel (человекочитаемое имя), kSecAttrSubject (DN владельца), kSecAttrIssuer (DN издателя).

Класс KeychainНазначениеТип данных
kSecClassGenericPasswordПароль приложенияData (NSString)
kSecClassInternetPasswordПароль к серверуData + атрибуты сервера
kSecClassCertificateСертификат X.509SecCertificate
kSecClassKeyКриптографический ключSecKey
kSecClassIdentityКлюч + сертификатSecIdentity

Работа с Keychain через API

Основной интерфейс взаимодействия с Keychain в нативном коде iOS — функции Security framework. Для Swift и Objective-C доступен один C-интерфейс, обёрнутый в удобные функции.

Базовые операции SecItemAdd и SecItemCopyMatching

Функция SecItemAdd добавляет новый элемент в Keychain. На вход принимает словарь с классом, данными и атрибутами. Возвращает статус errSecSuccess (0) или код ошибки. Функция SecItemCopyMatching выполняет поиск по атрибутам и возвращает найденные данные.

Для поиска используется флаг kSecReturnData — если true, функция возвращает содержимое записи. Флаг kSecMatchLimit определяет количество результатов: kSecMatchLimitOne (один) или kSecMatchLimitAll (все).

swift
func readPassword(service: String, account: String) -> Data? {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account,
        kSecReturnData as String: true,
        kSecMatchLimit as String: kSecMatchLimitOne
    ]
    var item: CFTypeRef?
    let status = SecItemCopyMatching(query as CFDictionary, &item)
    guard status == errSecSuccess else { return nil }
    return item as? Data
}

Удаление и обновление записей

SecItemUpdate позволяет изменить атрибуты или данные существующей записи. SecItemDelete удаляет все записи, соответствующие переданному словарю. При удалении важно указать достаточное количество атрибутов, чтобы случайно не удалить чужие записи в shared keychain.

swift
func deletePassword(service: String, account: String) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account
    ]
    SecItemDelete(query as CFDictionary)
}

Уровни доступа и защита данных

Каждая запись Keychain имеет атрибут kSecAttrAccessible, который определяет, когда данные доступны для чтения. Это критически важно для безопасности: неправильный уровень доступа может сделать данные уязвимыми или, наоборот, недоступными в нужный момент.

Константы доступности

kSecAttrAccessibleWhenUnlocked — данные доступны только когда устройство разблокировано. kSecAttrAccessibleAfterFirstUnlock — доступны после первой разблокировки после перезагрузки. kSecAttrAccessibleAlways — доступны всегда (не рекомендуется). Постфикс ThisDeviceOnly запрещает перенос данных через резервное копирование.

На устройствах с Secure Enclave ключ шифрования Keychain может быть дополнительно защищён биометрией: kSecAccessControlBiometryCurrentSet или kSecAccessControlUserPresence. Это добавляет требование Face ID или Touch ID для каждой операции чтения.

iCloud Keychain и синхронизация

iCloud Keychain синхронизирует записи между устройствами Apple через сквозное шифрование (end-to-end). Apple не имеет доступа к расшифрованным данным. Для включения синхронизации добавьте атрибут kSecAttrSynchronizable со значением kCFBooleanTrue.

Важно: синхронизируемые записи не могут содержать атрибут ThisDeviceOnly, так как они должны быть доступны на других устройствах. При потере всех устройств iCloud Keychain восстанавливается через код восстановления или резервный ключ iCloud.

Best Practices для выбора уровня доступа

Для токенов аутентификации используйте kSecAttrAccessibleWhenUnlockedThisDeviceOnly — данные доступны только при разблокированном устройстве и не копируются в бэкап. Для сертификатов, которые должны быть доступны фоновым задачам, используйте kSecAttrAccessibleAfterFirstUnlock. Never используйте kSecAttrAccessibleAlways для конфиденциальных данных.

Рекомендуется всегда добавлять постфикс ThisDeviceOnly для данных, не требующих синхронизации. Это предотвращает случайное копирование secrets в iCloud или iTunes backup, где они могут быть извлечены инструментами анализа. Для критических данных комбинируйте доступность с kSecAccessControlUserPresence — это добавляет требование биометрии или кода для расшифровки записи.

При использовании iCloud Keychain учитывайте, что синхронизируемые записи доступны на всех устройствах пользователя: если злоумышленник получит доступ к одному устройству, данные могут быть скомпрометированы на всех. Для изолированных secrets используйте ThisDeviceOnly.

Часто задаваемые вопросы

Чем Keychain отличается от UserDefaults?

UserDefaults хранит данные в открытом виде в файле .plist, доступном при анализе IPA. Keychain шифрует каждую запись отдельно, использует аппаратное шифрование и поддерживает уровни доступа, биометрию и синхронизацию через iCloud.

Как очистить Keychain при тестировании?

При каждом запуске на симуляторе iOS Keychain очищается. На реальном устройстве удалите приложение — iOS удалит все Keychain-записи этого разработчика. Для выборочной очистки вызовите SecItemDelete с соответствующими атрибутами.

Могут ли два приложения использовать общий Keychain?

Да, через keychain access groups. Приложения должны иметь одинаковый team ID в подписи и entitlements c одинаковым keychain-access-groups. Разработчик настраивает общий доступ в Xcode Capabilities.

Какой максимальный размер данных в Keychain?

Apple не документирует строгий лимит, но на практике рекомендуется не превышать 1–4 КБ на запись. Для больших объёмов используйте шифрование файлов и хранение ключа в Keychain, а сами данные — в Documents.

Безопасен ли Keychain при джейлбрейке?

При джейлбрейке защита Keychain снижается, так как злоумышленник получает root-доступ и может читать Keychain SQLite напрямую. Для критических данных используйте дополнительное шифрование с ключом, полученным с сервера.

Итоги

  • Keychain — защищённое хранилище iOS для паролей, ключей и сертификатов с аппаратным шифрованием AES-256
  • Security framework предоставляет C-API: SecItemAdd для записи, SecItemCopyMatching для чтения, SecItemDelete для удаления
  • Классы данных Keychain: GenericPassword, InternetPassword, Certificate, Key, Identity — каждый со своим набором атрибутов
  • kSecAttrAccessible управляет уровнем доступа: WhenUnlocked, AfterFirstUnlock, Always, с опцией ThisDeviceOnly
  • iCloud Keychain синхронизирует записи между устройствами через сквозное шифрование с атрибутом kSecAttrSynchronizable
  • Биометрия (Face ID / Touch ID) защищает доступ к Keychain через kSecAccessControlBiometryCurrentSet
  • Используйте Keychain для хранения токенов OAuth, паролей и криптографических ключей — не храните секреты в UserDefaults

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также