是否可以更新Keychain项的kSecAttrAccessible值? [英] Is it possible to update a Keychain item's kSecAttrAccessible value?

查看:416
本文介绍了是否可以更新Keychain项的kSecAttrAccessible值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to update the value of the attribute kSecAttrAccessible of existing items in the Keychain? It seems that it cannot be changed after the item was added to the Keychain. The following steps back up my assumption.

向钥匙串添加新项目:

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

The problem with this approach is that updateItemStatus always results in the status errSecUnimplemented.

我认为应该可以更新 kSecAttrAccessible 的值,因为应用程序的要求会发生变化。如果应用程序过去向Keychain添加了10个项目而未使用 kSecAttrAccessible 指定保护类,该怎么办?如果开发人员未明确设置保护类,则Keychain会隐式地为新项目分配值 kSecAttrAccessibleWhenUnlocked 。稍后,开发人员需要将保护类更改为 kSecAttrAccessibleAfterFirstUnlock ,因为应用程序必须在后台访问它(多任务处理)。开发人员如何实现这一目标?

I think it should be possible to update the value of kSecAttrAccessible because requirements of applications change. What if an application added ten items to the Keychain in the past without specifying the protection class with kSecAttrAccessible. The Keychain implicitly assigns new items the value kSecAttrAccessibleWhenUnlocked if the protection class is not set explicitly by the developer. Later, the developer needs to change the protection class to kSecAttrAccessibleAfterFirstUnlock because the application must access it in the background (Multitasking). How can the developer accomplish that?

Apple开发者论坛中已有一个帖子,但尚未得出答案:https://devforums.apple.com/thread/87646?tstart=0

There is already a thread in the Apple Developer Forums, but it has not yielded an answer yet: https://devforums.apple.com/thread/87646?tstart=0

推荐答案

在Apple开发者技术支持(ADTS)上打开支持事件后,我收到了回复此问题的回复。 SecItemUpdate()需要通过属性 kSecValueData 的Keychain项目数据来执行属性 kSecAttrAccessible 。根据ADTS,此约束目前未在参考文档中记录。

After opening a support incident at Apple Developer Technical Support (ADTS), I received a reply that answers this question. SecItemUpdate() requires the Keychain item's data via the attribute kSecValueData to perform the update of the attribute kSecAttrAccessible. According to ADTS, this constraint is currently not documented in the reference documentation.

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

这篇关于是否可以更新Keychain项的kSecAttrAccessible值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆