6

我需要更新钥匙串条目的 kSecAttrAccessible。我不需要更新实际数据,只需更新可访问性属性。

首先,我尝试找到该项目以确保我的查询字典是好的:

sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)(queryPrivateKey), (void *)&privateKeyRef);

此行成功找到我要查找的项目(返回代码为 0)。

然后我使用相同的查询更新 kSecAttrAccessible 属性:

if (sanityCheck == noErr && privateKeyRef != nil) {
    // found it, update accessibility
    NSMutableDictionary *updatedAttributes = [[NSMutableDictionary alloc] init];
    updatedAttributes[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAlways;
    OSStatus updateItemStatus = SecItemUpdate((__bridge CFDictionaryRef)queryPrivateKey, (__bridge CFDictionaryRef)updatedAttributes);
}

此时,updateItemStatus 为 -50 (paramErr)。

我看过这个帖子:Is it possible to update a Keychain item's kSecAttrAccessible value? 但是我的问题是不同的。即使我将 kSecValueData 添加到我的updatedAttributes. 此外,文档还指出我们只需要为 iOS 4 和更早版本添加 kSecValueData。我支持 iOS 7 及更高版本,所以这不应该是我的问题。

谁能指出我在这里缺少什么?非常感谢。

4

1 回答 1

5

查询可以通过 SecItemCopyMatching 成功找到您的钥匙串项这一事实并不意味着可以使用相同的查询来更新钥匙串项。

我正在使用以下查询进行项目查找:

[queryPrivateKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[queryPrivateKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[queryPrivateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
[queryPrivateKey setObject:[EncryptionHelper privateKeyTag:JWT_KEYPAIR_TAG] forKey:(__bridge id<NSCopying>)(kSecAttrApplicationTag)];

sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)(queryPrivateKey), (void *)&privateKeyef);

但是,为了使用此查询进行项目更新,我首先必须这样做:

[queryPrivateKey removeObjectForKey:(__bridge id)kSecReturnRef];

然后我可以更新:

OSStatus updateItemStatus = SecItemUpdate((__bridge CFDictionaryRef)queryPrivateKey,(__bridge CFDictionaryRef)updatedAttributes);

显然,kSecReturnRef在 的查询字典中不是可接受的键SecItemUpdate。我无法从苹果文档中找到 SecItemUpdate 查询的可接受键列表。从SecItemUpdate的文档来看,似乎只有这些键是可以接受的,但这似乎不是正确的列表,因为我希望像kSecClassetc 这样的键在列表中。如果有人有更新的文档链接,请分享它,现在我只需要一些试验和错误来找出哪些键是可以接受的SecItemUpdate

找到该项目后,更新还有另一个复杂性kSecAttrAccessible:您无法从更高的安全设置更新kSecAttrAccessibleWhenUnlocked到较低的设置,例如kSecAttrAccessibleAlways出于安全原因锁定手机时,因此必须在手机处于安全状态时进行迁移解锁。迁移的好地方是当应用程序在前台恢复时,因为当应用程序在前台时设备必须处于解锁状态。

于 2015-05-26T23:56:28.127 回答