Возможно ли обновить значение KeyShain kSecAttrAccessible?
Возможно ли обновить значение атрибута kSecAttrAccessible
существующих элементов в цепочке ключей? Кажется, что он не может быть изменен после добавления элемента в брелок. Следующие шаги подтверждают мое предположение.
Добавить новый элемент в брелок:
NSData *encodedIdentifier = [@"BUNDLE_IDENTIFIER"
dataUsingEncoding:NSUTF8StringEncoding];
NSData *encodedPassword = [@"PASSWORD"
dataUsingEncoding:NSUTF8StringEncoding];
// Construct a Keychain item
NSDictionary *keychainItem =
[NSDictionary dictionaryWithObjectsAndKeys:
kSecClassGenericPassword, kSecClass,
encodedIdentifier, kSecAttrGeneric,
encodedIdentifier, kSecAttrService,
@"USERNAME", kSecAttrAccount,
kSecAttrAccessibleWhenUnlocked, kSecAttrAccessible,
encodedPassword, kSecValueData
nil];
// Add item to Keychain
OSStatus addItemStatus = SecItemAdd((CFDictionaryRef)keychainItem, NULL);
В более позднее время измените атрибут kSecAttrAccessible
от kSecAttrAccessibleWhenUnlocked
до kSecAttrAccessibleAfterFirstUnlock
:
NSData *encodedIdentifier = [@"BUNDLE_IDENTIFIER"
dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
kSecClassGenericPassword, kSecClass,
encodedIdentifier, kSecAttrGeneric,
encodedIdentifier, kSecAttrService,
nil];
NSDictionary *updatedAttributes =
[NSDictionary dictionaryWithObject:kSecAttrAccessibleAfterFirstUnlock
forKey:kSecAttrAccessible];
OSStatus updateItemStatus = SecItemUpdate((CFDictionaryRef)query,
(CFDictionaryRef)updatedAttributes);
Проблема с этим подходом заключается в том, что updateItemStatus
всегда приводит к статусу errSecUnimplemented
.
Я думаю, что должно быть возможно обновить значение kSecAttrAccessible
, потому что требования приложений меняются. Что делать, если приложение добавило десять элементов в брелок в прошлом, не указав класс защиты с kSecAttrAccessible
. Keychain неявно назначает новым элементам значение kSecAttrAccessibleWhenUnlocked
, если класс защиты не задан явно разработчиком. Позже разработчику необходимо изменить класс защиты на kSecAttrAccessibleAfterFirstUnlock
, потому что приложение должно получить к нему доступ в фоновом режиме (многозадачность). Как разработчик может это сделать?
На форумах разработчиков Apple уже есть поток, но пока он еще не дал ответа: https://devforums.apple.com/thread/87646?tstart=0
Ответы
Ответ 1
После открытия поддержки в технической поддержке Apple Developer (ADTS), я получил ответ, который отвечает на этот вопрос. SecItemUpdate()
требует данных элемента Keychain через атрибут kSecValueData
для выполнения обновления атрибута kSecAttrAccessible
. Согласно ADTS, это ограничение в настоящее время не зарегистрировано в справочной документации.
NSData *encodedIdentifier = [@"BUNDLE_IDENTIFIER"
dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
kSecClassGenericPassword, kSecClass,
encodedIdentifier, kSecAttrGeneric,
encodedIdentifier, kSecAttrService,
nil];
// Obtain the Keychain item data via SecItemCopyMatching()
NSData *itemData = ...;
NSDictionary *updatedAttributes =
[NSDictionary dictionaryWithObjectsAndKeys:
kSecAttrAccessibleAfterFirstUnlock, kSecAttrAccessible,
(CFDataRef)itemData, kSecValueData,
nil];
OSStatus updateItemStatus = SecItemUpdate((CFDictionaryRef)query,
(CFDictionaryRef)updatedAttributes);
// updateItemStatus should have the value errSecSuccess
Ответ 2
Мне не удалось получить другой ответ на работу. Я закончил тестирование kSecAttrAccessibile, и если бы это было не то, что я хотел, я записал значение и атрибуты в цепочке ключей в локальных переменных, reset keychain, задал kSecAttrAccessible по желанию, а затем установил значение и атрибуты в цепочке ключей к их оригинальному настройки.