iOS keychain: SecItemUpdate returns -50 (paramErr) 更新 kSecAttrAccessible

iOS keychain: SecItemUpdate returns -50 (paramErr) when updating kSecAttrAccessible

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

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

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

这一行成功地找到了我要找的项目(return 代码是 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? 但是我的问题是不同的。它 returns -50 即使我将 kSecValueData 添加到我的 updatedAttributes。此外,文档还指出我们只需要为 iOS 4 及更早版本添加 kSecValueData。我支持 iOS 7 及更高版本,所以这不应该是我的问题。

有人能指出我在这里遗漏了什么吗?非常感谢。

查询可以通过 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, it seems that only these keys 的文档是可以接受的,但这似乎不是正确的列表,因为我希望 kSecClass 等键在列表中。如果有人有更新的文档 link 请分享它,现在我只需要反复试验才能找出 SecItemUpdate.

可接受的密钥

找到项目后,更新 kSecAttrAccessible 还存在另一个复杂性:您无法从 kSecAttrAccessibleWhenUnlocked 等较高安全设置更新到 [=19= 等较低安全设置] 当 phone 出于安全原因被锁定时,因此迁移必须在 phone 解锁时发生。迁移的好地方是当应用程序在前台恢复时,因为当应用程序在前台时设备必须处于解锁状态。