Keychain Services的文档非常不完整,当我尝试使用SecItem *()函数时,我一直收到无用的错误。目前,我试图删除之前添加到钥匙串中的身份:
// Identity ref is a persistent reference to the identity I want to delete.
NSData *identityRef = ...
NSDictionary *query = @{ (id)kSecClass: (id)kSecClassIdentity,
(id)kSecValuePersistentRef: identityRef };
OSStatus status = SecItemDelete((CFDictionaryRef)query);
// Fails with errSecParam (-50) under iOS 6
// Fails with errSecNotAvailable (-25291) under iOS 7
但是,据我所知,每个安全项类的所需(和推荐)参数都没有记录在任何地方。为了成功处理钥匙串中的身份,我应该指定什么?
修改
我还尝试使用kSecMatchItemList
作为记录:
NSDictionary *query = @{ (id)kSecClass: (id)kSecClassIdentity,
(id)kSecMatchItemList: @[identityRef] };
OSStatus status = SecItemDelete((CFDictionaryRef)query);
// Fails with errSecParam (-50)
我还尝试从this SO question指定建议的主键:
NSDictionary *attrs = nil;
NSDictionary *attrsQuery = @{ (id)kSecClass: (id)kSecClassIdentity,
(id)kSecValuePersistentRef: identityRef };
SecItemCopyMatching(attrsQuery, (CFTypeRef *)&attrs);
NSDictionary *query = @{ (id)kSecClass: (id)kSecClassIdentity,
(id)kSecAttrCertificateType: attrs[(id)kSecAttrCertificateType],
(id)kSecAttrIssuer: attrs[(id)kSecAttrIssuer],
(id)kSecAttrSerialNumber: attrs[(id)kSecAttrSerialNumber],
(id)kSecAttrApplicationLabel: attrs[(id)kSecAttrApplicationLabel],
(id)kSecAttrApplicationTag: attrs[(id)kSecAttrApplicationTag],
(id)kSecAttrKeyType: attrs[(id)kSecAttrKeyType],
(id)kSecAttrKeySizeInBits: attrs[(id)kSecAttrKeySizeInBits],
(id)kSecAttrEffectiveKeySize: attrs[(id)kSecAttrEffectiveKeySize] };
OSStatus status = SecItemDelete(query);
// Still fails with errSecParam (-50)
答案 0 :(得分:3)
看来我过度指定了要删除的项目。如果在从密钥链中删除标识时在查询中包含kSecClass
密钥,则Keychain服务会变得混乱。此代码有效:
NSData *identityRef = ...
NSDictionary *query = @{ (id)kSecValuePersistentRef: identityRef };
OSStatus status = SecItemDelete((CFDictionaryRef)query); // Success!
答案 1 :(得分:0)
Keychain可以看作是一个包含许多表(kSecClass)的数据库。
由于您正在使用kSecClassIdentity
这个"表"有两个主键,kSecClassKey
和kSecClassCertificate
。
在对条目执行操作时,应始终指定这些值。在您的情况下,您的查询字典缺少这些值。
您可以查看此SO帖子,了解有关钥匙串类主键的更多信息