是否可以更新钥匙串(keychain)中现有项目的属性kSecAttrAccessible的值?在将项目添加到钥匙串(keychain)后,似乎无法更改它。以下步骤支持我的假设。

将新项目添加到钥匙串(keychain):

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)添加了十个项目,该怎么办?如果开发人员未明确设置保护类,则钥匙串(keychain)会为新项目隐式分配kSecAttrAccessibleWhenUnlocked值。以后,开发人员需要将保护类更改为kSecAttrAccessibleAfterFirstUnlock,因为应用程序必须在后台访问它(多任务)。开发人员如何才能做到这一点?

苹果开发者论坛中已经有一个主题,但尚未给出答案:https://devforums.apple.com/thread/87646?tstart=0

最佳答案

在Apple开发人员技术支持(ADTS)发生支持事件后,我收到了答复此问题的答复。 SecItemUpdate()通过属性kSecValueData要求钥匙串(keychain)项的数据来执行属性kSecAttrAccessible的更新。根据ADTS,此约束当前未在引用文档中记录。

NSData *encodedIdentifier = [@"BUNDLE_IDENTIFIER"
                             dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
                       kSecClassGenericPassword, kSecClass,
                       encodedIdentifier, kSecAttrGeneric,
                       encodedIdentifier, kSecAttrService,
                       nil];

// Obtain the Keychain item's 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

关于iphone - 是否可以更新钥匙串(keychain)项目的kSecAttrAccessible值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5369238/

10-13 04:07