如何使用SecIdentityRef或持久性引用从密钥链中删除标识?

时间:2014-05-20 14:18:38

标签: ios keychain

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)

2 个答案:

答案 0 :(得分:3)

看来我过度指定了要删除的项目。如果在从密钥链中删除标识时在查询中包含kSecClass密钥,则Keychain服务会变得混乱。此代码有效:

NSData *identityRef = ...
NSDictionary *query = @{ (id)kSecValuePersistentRef: identityRef };
OSStatus status = SecItemDelete((CFDictionaryRef)query); // Success!

答案 1 :(得分:0)

Keychain可以看作是一个包含许多表(kSecClass)的数据库。

由于您正在使用kSecClassIdentity这个"表"有两个主键,kSecClassKeykSecClassCertificate

在对条目执行操作时,应始终指定这些值。在您的情况下,您的查询字典缺少这些值。

您可以查看此SO帖子,了解有关钥匙串类主键的更多信息

What makes a keychain item unique (in iOS)?