gpt4 book ai didi

ios - 钥匙串(keychain):项目报告为 errSecItemNotFound,但在添加时收到 errSecDuplicateItem

转载 作者:IT王子 更新时间:2023-10-29 07:50:21 36 4
gpt4 key购买 nike

这个问题困扰我好久了,希望有大侠能指点一下。本质上,我有 一小部分 的用户无法将项目保存/更新到钥匙串(keychain)。有问题的控制流程如下:

  1. 我们使用 SecItemCopyMatching 检查项目是否存在。这将返回错误代码 errSecItemNotFound

  2. 然后我们尝试通过 SecItemAdd 添加项目,但这随后返回 errSecDuplicateItem

因此,我们有一些用户根本无法更新钥匙串(keychain)项目的子集,要求他们恢复设备以清除钥匙串(keychain)。这显然是一个 Not Acceptable 解决方法。以前似乎对他们有用,但现在进入了这个不可更新的循环。

经过研究,我发现有关 SecItemCopyMatching 中使用的搜索查询不够具体的问题,但我的代码尽可能使用了常见的搜索查询。

+ (NSMutableDictionary*)queryForUser:(NSString*)user key:(NSString*)key
{
if (!key || !user) { return nil; }

NSString* bundleId = [[NSBundle mainBundle] bundleIdentifier];
NSString* prefixedKey = [NSString stringWithFormat:@"%@.%@", bundleId, key];

NSMutableDictionary* query = [NSMutableDictionary dictionary];
[query addEntriesFromDictionary:@{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword}];
[query addEntriesFromDictionary:@{(__bridge id)kSecAttrAccount : user}];
[query addEntriesFromDictionary:@{(__bridge id)kSecAttrService : prefixedKey}];
[query addEntriesFromDictionary:@{(__bridge id)kSecAttrLabel : prefixedKey}];
[query addEntriesFromDictionary:@{(__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly}];

return query;
}

执行更新/添加的代码如下(抱歉冗长):

// Setup the search query, to return the *attributes* of the found item (for use in SecItemUpdate)
NSMutableDictionary* query = [self queryForUser:username key:key];
[query addEntriesFromDictionary:@{(__bridge id)kSecReturnAttributes : (__bridge id)kCFBooleanTrue}];

// Prep the dictionary we'll use to update/add the new value
NSDictionary* updateValues = @{(__bridge id) kSecValueData : [value dataUsingEncoding:NSUTF8StringEncoding]};

// Copy what we (may) already have
CFDictionaryRef resultData = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef*)&resultData);

// If it already exists, update it
if (status == noErr) {
// Create a new query with the found attributes
NSMutableDictionary* updateQuery = [NSMutableDictionary dictionaryWithDictionary:(__bridge NSDictionary*)resultData];
[updateQuery addEntriesFromDictionary:@{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword}];

// Update the item in the keychain
status = SecItemUpdate((__bridge CFDictionaryRef)updateQuery, (__bridge CFDictionaryRef)updateValues);

if (status != noErr) {
// Update failed, I've not seen this case occur as of yet
}
}
else {
// Add the value we want as part of our original search query, and add it to the keychain
[query addEntriesFromDictionary:updateValues];
[query removeObjectForKey:(__bridge id)kSecReturnAttributes];
status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);

if (status != noErr) {
// Addition failed, this is where I'm seeing errSecDuplicateItem
}
}

我们尝试使用 SecItemDelete 而不是检查/更新,但这也返回了 errSecItemNotFound 并且 SecItemAdd 之后直接失败。删除代码为:

+ (BOOL)deleteItemForUser:(NSString *)username withKey:(NSString *)itemKey {
if (!username || !itemKey) { return NO; }

NSString * bundleId = [[NSBundle mainBundle] bundleIdentifier];
NSString * prefixedItemKey = [NSString stringWithFormat:@"%@.%@", bundleId, itemKey];

NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: (__bridge id)kSecClassGenericPassword, kSecClass,
username, kSecAttrAccount,
prefixedItemKey, kSecAttrService, nil];

OSStatus status = SecItemDelete((__bridge CFDictionaryRef) query);

if (status != noErr) {
// Failed deletion, returning errSecItemNotFound
}

return (status == noErr);
}

虽然我们为应用程序定义了 2 个钥匙串(keychain)访问组,但受影响的钥匙串(keychain)项没有分配作为属性的访问组(根据文档,这意味着将对所有访问组进行搜索)。除了 errSecItemNotFounderrSecDuplicateItem 之外,我还没有看到任何其他错误代码。

只有一小部分用户会遇到这种情况,这让我很困惑。关于可能导致此问题的钥匙串(keychain),关于多线程、刷新、后台访问等,我是否需要考虑任何其他注意事项?

非常感谢帮助。我宁愿坚持使用 Keychain Services API 而不是使用第 3 方库。我想了解这里的根本问题。

最佳答案

kSecClassGenericPassword 的唯一 key 由;

kSecAttrAccount
kSecAttrService

要检查其是否存在,请仅使用这些属性(包括 kSecReturnAttributes 标志)查询钥匙串(keychain)存储。

包括 kSecAttrLabelkSecAttrAccessible 将排除任何具有相同唯一键但具有不同属性的现有项目。

确认其(不)存在后,添加附加属性并添加或更新。

关于ios - 钥匙串(keychain):项目报告为 errSecItemNotFound,但在添加时收到 errSecDuplicateItem,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22403734/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com