0Pricing
Swift Academy · Урок

Управление доступом к связке ключей

Защищайте элементы биометрией и разблокировкой устройства.

«Управление доступом к связке ключей» — бесплатный урок Swift Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.

Управление моментом чтения секретов

Сохранение секрета — лишь половина задачи: необходимо контролировать когда его можно прочитать. Связка ключей предлагает классы доступности и флаги управления доступом, ограничивающие доступ к элементам состоянием разблокировки устройства, кодом-паролем или биометрией. Это защищает данные при потере устройства.

import Security
// Two layers of control:
//   kSecAttrAccessible  -> when readable (lock state)
//   SecAccessControl    -> user presence / biometrics

Ключ kSecAttrAccessible

kSecAttrAccessible задаёт класс доступности при добавлении элемента. Он определяет, доступен ли элемент всегда, только после первой разблокировки или только пока устройство разблокировано. Выбирайте наиболее строгий уровень, который допускает функция.

import Security
let query: [String: Any] = [
    kSecClass as String: kSecClassGenericPassword,
    kSecAttrAccount as String: "user",
    kSecValueData as String: Data("secret".utf8),
    kSecAttrAccessible as String:
        kSecAttrAccessibleWhenUnlocked
]
_ = query

WhenUnlocked

kSecAttrAccessibleWhenUnlocked делает элемент доступным для чтения только пока устройство разблокировано. Фоновые задачи, выполняющиеся при заблокированном устройстве, не смогут получить к нему доступ. Для большинства токенов сеанса это разумный вариант по умолчанию.

import Security
// Readable only while unlocked; blocked when locked.
let level = kSecAttrAccessibleWhenUnlocked
_ = level

AfterFirstUnlock

kSecAttrAccessibleAfterFirstUnlock сохраняет доступность элемента с первой разблокировки после запуска устройства до следующей перезагрузки — даже если впоследствии устройство заблокировано. Используйте этот вариант для секретов, необходимых фоновому процессу, например для токена обработки push-уведомлений.

import Security
// Available after the first unlock post-boot,
// including while subsequently locked.
let level = kSecAttrAccessibleAfterFirstUnlock
_ = level

Варианты ThisDeviceOnly

У каждого класса доступности есть вариант ...ThisDeviceOnly. Такие элементы не включаются в зашифрованные резервные копии и никогда не переносятся на новое устройство. Используйте их для ключей, которые не должны покидать это устройство.

import Security
// Never backed up, never migrated:
let local = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
_ = local

Когда установлен код-пароль

kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly сохраняет элемент только при наличии у пользователя кода-пароля и удаляет его, если код-пароль убран. Это гарантирует, что секрет всегда защищён кодом-паролем.

import Security
let level =
    kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
// Item vanishes if the user disables their passcode.
_ = level

SecAccessControl для аутентификации пользователя

Помимо состояния блокировки, SecAccessControlCreateWithFlags создаёт политику, требующую явной аутентификации пользователя — с помощью биометрии или кода-пароля — в момент чтения. Её назначают через kSecAttrAccessControl вместо ключа доступности или вместе с ним.

import Security
func makeControl() -> SecAccessControl? {
    return SecAccessControlCreateWithFlags(
        nil,
        kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
        .userPresence,
        nil)
}

Флаги управления доступом

Флаги уточняют требование: .userPresence разрешает биометрию или переход к коду-паролю; .biometryCurrentSet делает элемент недействительным при изменении зарегистрированных отпечатков или лиц; .devicePasscode принудительно требует ввода кода-пароля. Сочетайте их, чтобы выразить необходимые требования безопасности.

import Security
// .userPresence        -> biometric OR passcode
// .biometryAny         -> any enrolled biometric
// .biometryCurrentSet  -> invalidate on biometric change
// .devicePasscode      -> passcode only
let flags: SecAccessControlCreateFlags = [.userPresence]
_ = flags

Добавление защищённого элемента

Чтобы сохранить секрет, защищённый биометрией, поместите объект SecAccessControl в kSecAttrAccessControl. При любом последующем чтении система попросит пользователя пройти аутентификацию, прежде чем вернуть данные.

import Security
func saveProtected(_ data: Data, account: String,
                   control: SecAccessControl) -> Bool {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: account,
        kSecValueData as String: data,
        kSecAttrAccessControl as String: control]
    return SecItemAdd(query as CFDictionary, nil)
        == errSecSuccess
}

Чтение запрашивает аутентификацию

Чтение защищённого элемента автоматически запускает интерфейс аутентификации. С помощью kSecUseOperationPrompt можно передать строку с объяснением причины, чтобы запрос сообщал, зачем нужен доступ. Чтение приостанавливается, пока пользователь не пройдёт аутентификацию или не отменит операцию.

import Security
func readProtected(account: String) -> Data? {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: account,
        kSecReturnData as String: true,
        kSecUseOperationPrompt as String:
            String(localized: "Unlock your saved key")]
    var out: CFTypeRef?
    return SecItemCopyMatching(query as CFDictionary,
        &out) == errSecSuccess ? out as? Data : nil
}

Выбор подходящего уровня

Сопоставляйте политику с риском:

  • Токен сеанса, используемый в фоновом режиме: AfterFirstUnlock.
  • Токен, используемый только в интерфейсе: WhenUnlocked.
  • Особо важный секрет: SecAccessControl с .userPresence и классом ThisDeviceOnly.

Более строгий уровень безопаснее, но блокирует фоновый доступ — учитывайте оба требования.

import Security
// High-value: biometric-gated, device-bound, no backup
let control = SecAccessControlCreateWithFlags(
    nil,
    kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
    .userPresence, nil)
_ = control

Быстрая проверка

Вспомните, какой класс доступности подходит для секрета, необходимого в фоновом режиме.

Итоги

Вы научились ограничивать доступ к элементам Связки ключей:

  • kSecAttrAccessible задаёт доступность в зависимости от состояния блокировки: WhenUnlocked, AfterFirstUnlock и варианты ...ThisDeviceOnly, не включаемые в резервные копии.
  • WhenPasscodeSetThisDeviceOnly связывает элемент с наличием кода-пароля.
  • SecAccessControl с такими флагами, как .userPresence или .biometryCurrentSet, требует аутентификации в момент чтения.
  • Выбирайте наиболее строгий уровень, который всё ещё допускает нужный сценарий доступа.

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

Урок «Управление доступом к связке ключей» бесплатный?

Да — полный текст урока «Управление доступом к связке ключей» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.

Чему я научусь в уроке «Управление доступом к связке ключей»?

Защищайте элементы биометрией и разблокировкой устройства. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Управление доступом к связке ключей»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Хранение секретов в связке ключей
  2. Управление доступом к связке ключей
  3. Биометрическая аутентификация
  4. Защита данных и шифрование
← Назад к Swift Academy