Ответ
Для хранения конфиденциальных данных, таких как изображения, необходимо использовать защищенные API iOS. Никогда не храните секреты в UserDefaults, plist-файлах или в открытом виде в директориях Documents или Caches.
Рекомендуемые подходы:
-
Keychain Services: Лучший выбор для небольших данных (практический лимит ~4KB). Данные шифруются аппаратным ключом и защищены на уровне системы.
// Сохранение данных изображения в Keychain let imageData = UIImage(named: "secret")!.pngData()! let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrAccount as String: "com.yourapp.secretImage", kSecValueData as String: imageData, kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly // Строгий атрибут доступа ] SecItemAdd(query as CFDictionary, nil) -
Шифрование + Файловая система: Для больших файлов. Зашифруйте данные с помощью
CryptoKitперед записью в защищенную директорию.import CryptoKit // Генерация/хранение ключа — в Keychain! let key = SymmetricKey(size: .bits256) let imageData = try Data(contentsOf: imageURL) let sealedBox = try AES.GCM.seal(imageData, using: key) try sealedBox.combined?.write(to: encryptedFileURL) -
Secure Enclave: Максимальный уровень защиты для криптографических ключей (например, ключа для расшифровки файла). Доступно только на устройствах с FaceID/TouchID. Используется для операций с ключами, но не для хранения самих изображений.
Атрибуты доступа Keychain (kSecAttrAccessible): Используйте kSecAttrAccessibleWhenUnlockedThisDeviceOnly, чтобы данные были доступны только после разблокировки устройства и не копировались в резервные копии iCloud.
Ответ 18+ 🔞
Ну слушай, история такая: если у тебя в приложении есть какие-то конфиденциальные картинки, типа паспорта или там фоток с последней пьянки, которые не должны светиться, — ты их нихуя не должен пихать куда попало.
Вот смотри, какие есть варианты, чтобы не прослыть полным распиздяем:
1. Ключница (Keychain Services) Это как сейф для мелких штук. Идеально, если твои данные влезают в ~4 килобайта. Всё шифруется на аппаратном уровне, система сама охраняет. Главное — правильно дверцу закрыть.
// Сохранение данных изображения в Keychain
let imageData = UIImage(named: "secret")!.pngData()!
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "com.yourapp.secretImage",
kSecValueData as String: imageData,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly // Вот эта штука — чтобы только на разблокированном устройстве и никуда в iCloud!
]
SecItemAdd(query as CFDictionary, nil)
Видишь этот kSecAttrAccessibleWhenUnlockedThisDeviceOnly? Это чтобы твои секреты не утекали в бэкапы и требовали разблокировки телефона. Без этого — вообще никуда.
2. Шифрование + файловая система
А если картинка здоровенная, как твоё ЧСВ? Тогда сначала её надо превратить в тарабарщину с помощью CryptoKit, а потом уже куда-то складывать. Но ключ от этой тарабарщины — опять же в Ключницу, ёпта!
import CryptoKit
// Генерация/хранение ключа — в Keychain, блядь!
let key = SymmetricKey(size: .bits256)
let imageData = try Data(contentsOf: imageURL)
let sealedBox = try AES.GCM.seal(imageData, using: key)
try sealedBox.combined?.write(to: encryptedFileURL)
Получился файл, который выглядит как белиберда. Без ключа — нихуя не прочитать. Красота.
3. Secure Enclave Это уже для параноиков высшей лиги. Такая отдельная чёрная коробочка в процессоре, куда можно положить криптографический ключ (саму фотку — нет, она не влезет). Используется в связке с FaceID/TouchID. Если телефон вскроют и достанут чип — ключа там уже не будет. Вообще. Пиздец как надёжно.
Итог, чувак:
Запомни раз и навсегда — UserDefaults, plist-файлы или просто скидывание файлов в Documents для секретных данных — это уровень "я мудак". Это как оставить ключи от квартиры под ковриком, на котором написано "КЛЮЧИ ЗДЕСЬ".
Всё, что хоть немного конфиденциально — либо в Keychain с правильными атрибутами, либо зашифровано так, чтобы у охуевшего соседа глаза на лоб полезли. Выбирай.