是否可以更新钥匙串物品的kSecAttrAccessible值?

问题描述

| 是否可以更新钥匙串中现有项目的属性“ 0”的值?在将商品添加到钥匙串后,似乎无法更改。以下步骤支持我的假设。 向钥匙串添加新项目:
NSData *encodedIdentifier = [@\"BUNDLE_IDENTIFIER\" 
                             dataUsingEncoding:NSUTF8StringEncoding];
NSData *encodedPassword = [@\"PASSWORD\"
                           dataUsingEncoding:NSUTF8StringEncoding];

// Construct a Keychain item
NSDictionary *keychainItem = 
    [NSDictionary dictionaryWithObjectsAndKeys:
        kSecClassGenericPassword,kSecClass,encodedIdentifier,kSecAttrGeneric,kSecAttrService,@\"USERNAME\",kSecAttrAccount,kSecAttrAccessibleWhenUnlocked,kSecAttrAccessible,encodedPassword,kSecValueData
        nil];

// Add item to Keychain
OSStatus addItemStatus = SecItemAdd((CFDictionaryRef)keychainItem,NULL);
稍后,将属性“ 0”从“ 3”更改为“ 4”:
NSData *encodedIdentifier = [@\"BUNDLE_IDENTIFIER\" 
                             dataUsingEncoding:NSUTF8StringEncoding];

NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
                       kSecClassGenericPassword,nil];

NSDictionary *updatedAttributes = 
    [NSDictionary dictionaryWithObject:kSecAttrAccessibleAfterFirstUnlock 
                                forKey:kSecAttrAccessible];

OSStatus updateItemStatus = SecItemUpdate((CFDictionaryRef)query,(CFDictionaryRef)updatedAttributes);
这种方法的问题在于,“ 6”总是导致状态“ 7”。 我认为应该可以更新ѭ0的值,因为应用程序的要求会发生变化。如果应用程序过去在没有将保护等级指定为“ 0”的情况下向钥匙串添加了十个项目,该怎么办。如果开发人员未明确设置保护等级,则钥匙串将为新项目隐式分配值“ 3”。以后,开发人员需要将保护级别更改为“ 4”,因为应用程序必须在后台访问它(多任务)。开发人员如何才能做到这一点? 苹果开发者论坛中已经有一个主题,但尚未给出答案:https://devforums.apple.com/thread/87646?tstart=0     

解决方法

在Apple开发人员技术支持(ADTS)发生支持事件后,我收到了答复此问题的答复。
SecItemUpdate()
通过属性
kSecValueData
要求钥匙串项目的数据来执行属性
kSecAttrAccessible
的更新。根据ADTS,此约束当前未在参考文档中记录。
NSData *encodedIdentifier = [@\"BUNDLE_IDENTIFIER\" 
                             dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
                       kSecClassGenericPassword,kSecClass,encodedIdentifier,kSecAttrGeneric,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
    ,我无法获得其他答案。我结束了对kSecAttrAccessibile的测试,如果不是我想要的,我将密钥链中的值和属性记录在局部变量中,重置密钥链,根据需要设置kSecAttrAccessible,然后将密钥链中的值和属性设置为其原始设置。 。     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...