Как правильно хранить пароль в iOS Keychain?

«Как правильно хранить пароль в iOS Keychain?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Правильный подход: Использовать класс kSecClassGenericPassword с обязательными атрибутами для идентификации записи и настройками защиты.

Ключевые шаги и best practices:

  1. Используйте правильный класс: kSecClassGenericPassword предназначен для паролей и токенов.
  2. Задавайте уникальные идентификаторы: Комбинация kSecAttrAccount и kSecAttrService однозначно идентифицирует запись.
  3. Контролируйте доступ: Атрибут kSecAttrAccessible определяет, когда доступны данные (например, только после разблокировки устройства).
  4. Храните данные как Data: Конвертируйте строки в Data перед сохранением.

Пример сохранения пароля:

import Security

func savePassword(_ password: String, for account: String, service: String = "com.yourapp") -> Bool {

    guard let passwordData = password.data(using: .utf8) else { return false }

    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: account,
        kSecAttrService as String: service,
        kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly, // Высокий уровень защиты
        kSecValueData as String: passwordData
    ]

    // Сначала удаляем старую запись, если она есть
    SecItemDelete(query as CFDictionary)

    // Добавляем новую
    let status = SecItemAdd(query as CFDictionary, nil)
    return status == errSecSuccess
}

Рекомендации по безопасности:

  • kSecAttrAccessibleWhenUnlockedThisDeviceOnly — оптимальный выбор: данные доступны только после разблокировки и не синхронизируются с iCloud.
  • Не используйте kSecAttrAccessibleAlways — это небезопасно.
  • Проверяйте коды возврата (errSecSuccess, errSecItemNotFound) для обработки ошибок.
  • Для обновления используйте SecItemUpdate, для удаления — SecItemDelete с аналогичным query.