iOS 钥匙串:更新 kSecAttrAccess 时,SecItemUpdate 返回 -50 (paramErr)



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

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

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)。

我看过这个线程:是否可以更新钥匙串项目的 kSecAttrAccessible 值? 但是我的问题不同。即使我将 kSecValueData 添加到我的updatedAttributes,它也返回 -50。此外,文档还指出,我们只需要为iOS 4及更早版本添加kSecValueData。我支持iOS 7及更高版本,所以这不应该是我的问题。

谁能指出我在这里错过了什么?多谢。

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

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

[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 的文档来看,似乎只有这些键是可以接受的,但这似乎不是正确的列表,因为我希望像kSecClass等键在列表中。如果有人有更新的文档链接,请分享它,现在我只需要一些试验和错误来找出哪些密钥可以接受SecItemUpdate

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

相关内容

  • 没有找到相关文章

最新更新