是否有可能更新Keychain项目的kSecAttrAccessible值?

是否有可能更新Keychain中现有项目的属性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); 

稍后,将属性kSecAttrAccessiblekSecAttrAccessibleWhenUnlockedkSecAttrAccessibleAfterFirstUnlock

 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指定保护类, kSecAttrAccessible十个项目添加到Keychain中。 如果开发人员没有明确设置保护类,则Keychain会隐式分配新项目kSecAttrAccessibleWhenUnlocked 。 之后,开发人员需要将保护类更改为kSecAttrAccessibleAfterFirstUnlock因为应用程序必须在后台访问它(多任务处理)。 开发人员如何才能做到这一点?

苹果开发者论坛已经有一个线程,但是还没有得到答案: https : //devforums.apple.com/thread/87646?tstart=0

在Apple开发者技术支持部门(ADTS)发布支持事件后,我收到了一个答复,回答了这个问题。 SecItemUpdate()需要Keychain项目的数据通过属性kSecValueData来执行属性kSecValueData的更新。 根据ADTS,这个约束目前没有logging在参考文件中。

 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 

我无法得到其他答案的工作。 我结束了testingkSecAttrAccessibile,如果它不是我想要的,我logging在本地variables钥匙串中的值和属性,重置钥匙串,设置kSecAttrAccessible根据需要,然后将钥匙串中的值和属性设置为其原始设置。