Блестяще. Вы установили на компьютере профиль инициализации для вашего приложения. Воспользуйтесь настройками сборки проекта, чтобы убедиться в том, что выбран правильный профиль для схемы Debug (Отладка). Затем повторите описанный процесс при создании профилей Ad Hoc и App Store, чтобы гарантировать сборку приложения с нужными профилями для схемы Release (Выпуск).
Созданный вами профиль инициализации обеспечивает отладку ваших приложений на устройстве с iOS и удобное сохранение данных на диске с применением связки ключей.
См. также
Раздел 8.0.
8.2. Хранение значений в связке ключей
Постановка задачи
Требуется обеспечить безопасное хранение конфиденциальных данных в связке ключей.
Решение
Необходимо гарантировать, что ваше приложение будет скомпоновано с учетом требований фреймворка Security (Безопасность). Затем воспользуйтесь функцией SecItemAdd для добавления нового элемента в связку ключей приложения.
Обсуждение
API связки ключей в операционных системах iOS и OS X написаны на языке C. Таким образом, у нас нет мостика к Objective-C или какого-то промежуточного уровня, который предоставлял бы взаимодействие программы с API на C. Поэтому работать с этими API несколько сложнее, чем с обычными. Основной момент при изучении этих API заключается в том, что запросы, отправляемые к API связки ключей, обычно упакованы в словарях. Например, если требуется запросить у сервисов связки ключей безопасное хранение тех или иных данных, то вы помещаете этот запрос в словарь (а вместе с запросом — все данные, которые собираетесь хранить, ключ к этим данным, идентификатор приложения и т. д.). Этот словарь вы отправляете к API, примером которого может служить функция SecItemAdd. Чтобы хранить информационный фрагмент в связке ключей, создайте словарь со следующими ключами:
• kSecClass — при необходимости хранения конфиденциальных информационных фрагментов, например строк, в качестве значения этого ключа обычно задается kSecClassGenericPassword;
• kSecAttrService — значение ключа чаще всего представляет собой строку. Как правило, эта строка — идентификатор нашего приложения;
• kSecAttrAccount — значением является строка, указывающая ключ к значению, которое мы хотим сохранить. Это произвольная строка, которая должна иметь смысл для вас и в контексте приложения;
• kSecValueData — значением является экземпляр NSData, который вы хотите сохранить по указанному ключу (kSecAttrAccount).
Возвращаемое значение функции SecItemAdd относится к типу OSStatus. Различные значения, которые вы можете получить от этой функции, определяются в файле SecBase.h SDK. Поэтому, находясь в Xcode, просто нажмите комбинацию клавиш Command+Shift+O, введите SecBase.h и попробуйте найти значение errSecSuccess. После того как найдете errSecSuccess в перечне, вы сможете просмотреть остальные значения, которые могут быть возвращены в экземпляре OSStatus:
enum
{
errSecSuccess = 0,
errSecUnimplemented = -4,
errSecParam = -50,
errSecAllocate = -108,
errSecNotAvailable = -25291,
errSecDuplicateItem = -25299,
errSecItemNotFound = -25300,
errSecInteractionNotAllowed = -25308,
errSecDecode = -26275,
errSecAuthFailed = -25293,
};
Если функция SecItemAdd завершится успешно, то в качестве ее возвращаемого значения вы получите errSecSuccess. Иное значение, получаемое от этой функции, означает ошибку. Итак, давайте объединим изученное и сделаем небольшой код, который будет записывать строковое значение в связку ключей:
#import «AppDelegate.h»
#import
@implementation AppDelegate
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSString *key = @"Full Name";
NSString *value = @"Steve Jobs";
NSData *valueData = [value dataUsingEncoding: NSUTF8StringEncoding];
NSString *service = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary *secItem = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: service,
(__bridge id)kSecAttrAccount: key,
(__bridge id)kSecValueData: valueData,
};
CFTypeRef result = NULL;