Ответ
Правильный подход: Использовать класс kSecClassGenericPassword с обязательными атрибутами для идентификации записи и настройками защиты.
Ключевые шаги и best practices:
- Используйте правильный класс:
kSecClassGenericPasswordпредназначен для паролей и токенов. - Задавайте уникальные идентификаторы: Комбинация
kSecAttrAccountиkSecAttrServiceоднозначно идентифицирует запись. - Контролируйте доступ: Атрибут
kSecAttrAccessibleопределяет, когда доступны данные (например, только после разблокировки устройства). - Храните данные как
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.
Ответ 18+ 🔞
Да ты посмотри, что люди творят с этой Keychain, просто пиздец! Сидят, блядь, как мартышки, пытаются впендюрить туда что попало, а потом орут: «Ой, у меня токены утекли, блядь!». Так, слушай сюда, я тебе сейчас разжую, как это делать по-человечьи.
Нормальный, не распиздяйский подход: Юзай класс kSecClassGenericPassword и не забудь про обязательные атрибуты, чтобы потом самому не ебаться с поиском своей же записи.
Основные моменты, чтобы не облажаться:
- Класс, ёпта, правильный бери!
kSecClassGenericPassword— он как раз для паролей, токенов и прочей чувствительной хуйни. Не надо пытаться туда фотку кота пихать. - Уникально помечай! Связка
kSecAttrAccount(логин) иkSecAttrService(название твоего приложения) — это твой гарант, что ты не перепутаешь пароль от банка с паролем от «Одноклассников». - Контролируй доступ, а то проебёшься! Атрибут
kSecAttrAccessible— это твой главный охранник. Он решает, когда данные можно достать. Например, только после разблокировки телефона. - Данные — только в
Data! Строку свою любимую перед сохранением конвертируй вData, иначе Security Framework тебя просто пошлёт нахуй.
Вот, смотри, как сохранить пароль без кринжа:
import Security
func savePassword(_ password: String, for account: String, service: String = "com.yourapp") -> Bool {
// Сначала строку в Data, ебанашка!
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, // Жёсткий режим, синхронизации с iCloud нет
kSecValueData as String: passwordData
]
// Старую запись нахуй удаляем, чтобы не было конфликтов
SecItemDelete(query as CFDictionary)
// И втыкаем новую, свеженькую
let status = SecItemAdd(query as CFDictionary, nil)
return status == errSecSuccess // Вернёт true, если всё заебись
}
Теперь про безопасность, чтобы не просрать данные пользователей:
kSecAttrAccessibleWhenUnlockedThisDeviceOnly— это наш выбор, блядь! Данные только после разблокировки и только на этом устройстве. Никаких iCloud, никаких бэкапов в iTunes.- Забудь как страшный сон про
kSecAttrAccessibleAlways— это дыра размером с твою жопу, данные будут доступны всегда, даже если телефон в кармане у вора. - Проверяй статусы, ёпта!
errSecSuccess— ок,errSecItemNotFound— не нашли, обрабатывай это, не игнорируй. - Хочешь обновить?
SecItemUpdate. Удалить?SecItemDelete. Всё просто, не выёбывайся.