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

我需要更新钥匙串条目的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,它也会返回-50.此外,文档还指出我们只需要为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查询字典中的可接受键.我无法从Apple文档中找到SecItemUpdate查询的可接受键列表.从SecItemUpdate的文档来看,似乎只有these keys是可以接受的,但这似乎不是正确的列表,因为我期望像kSecclass等密钥在列表中.如果有人有更新的文档链接,请分享它,现在它只需要我一些试验和错误来找出SecItemUpdate可以接受哪些密钥.

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

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...