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 призначені для зберігання рядкових паролів. Інтернет-версія додатково зберігає дані сервера: домен, протокол, порт і шлях автентифікації. 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. Ніколи не використовуйте kSecAttrAccessibleAlways для конфіденційних даних.

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

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

Часті запитання

Чим Keychain відрізняється від UserDefaults?

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

Як очистити Keychain при тестуванні?

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

Чи можуть два додатки використовувати спільний Keychain?

Так, через keychain access groups. Додатки повинні мати однаковий team ID у підписі та entitlements з однаковим 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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