Ответ
Keychain Services — это стандартный и наиболее безопасный способ хранения конфиденциальных данных в iOS, macOS и др. Он обеспечивает аппаратное шифрование и изоляцию данных.
Базовое использование Keychain (без сторонних библиотек):
import Security
// 1. Сохранение данных (например, токена)
func saveToken(_ token: String, for account: String) -> Bool {
guard let tokenData = token.data(using: .utf8) else { return false }
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account, // Уникальный идентификатор (e.g., "user_access_token")
kSecAttrService as String: "com.yourapp.service", // Идентификатор вашего приложения
kSecValueData as String: tokenData,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked // Уровень доступа
]
// Сначала удаляем старую запись (если есть)
SecItemDelete(query as CFDictionary)
// Добавляем новую
let status = SecItemAdd(query as CFDictionary, nil)
return status == errSecSuccess
}
// 2. Извлечение данных
func loadToken(for account: String) -> String? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account,
kSecAttrService as String: "com.yourapp.service",
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var dataTypeRef: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
guard status == errSecSuccess, let data = dataTypeRef as? Data else { return nil }
return String(data: data, encoding: .utf8)
}
Ключевые аспекты безопасности:
-
kSecAttrAccessible: Определяет, когда доступны данные.kSecAttrAccessibleWhenUnlocked(рекомендуется по умолчанию) — только когда устройство разблокировано.kSecAttrAccessibleAfterFirstUnlock— после первой разблокировки до перезагрузки.kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly— максимальная защита, требует включенного пароля, не синхронизируется с iCloud.
-
Атрибуты
kSecAttrAccessGroupиkSecAttrSynchronizable:- Используйте
kSecAttrAccessGroupдля Shared Keychain между приложениями одной команды. kSecAttrSynchronizableпозволяет синхронизировать запись через iCloud Keychain (осторожно с конфиденциальными данными!).
- Используйте
Практические рекомендации:
- Не храните в UserDefaults/plist-файлах: Они не шифруются и легко извлекаются с джейлбрейкнутых устройств.
- Используйте обертки: Для удобства используйте проверенные библиотеки, такие как KeychainAccess.
import KeychainAccess let keychain = Keychain(service: "com.yourapp.service") keychain["user_access_token"] = "eyJhbGciOiJ..." let token = keychain["user_access_token"] - Для биометрической аутентификации: Используйте фреймворк LocalAuthentication вместе с Keychain, устанавливая политику доступа
kSecAccessControlBiometryCurrentSetв запросе. - Криптографические ключи: Для хранения асимметричных ключей (RSA, EC) используйте
kSecClassKey. Для генерации и хранения ключей в Secure Enclave используйтеkSecAttrTokenIDSecureEnclave.