3

我正在尝试通过钥匙串 API 从钥匙串中删除带有配对私钥的证书。我可以轻松删除证书,但私钥总是被遗忘。我怎样才能从钥匙串中删除它???我尝试了几种方法,但即使手头有 SecKeyRef,一旦我运行 SecItemDelete(例如),该函数返回 errSecSuccess 状态,但钥匙仍在钥匙串中!!!

非常感谢任何帮助,如果有任何示例代码,请发布。错了!这太令人沮丧了……

谢谢..

4

1 回答 1

0

嗯,这个问题的答案有点棘手......显然,有一个 Apple 已知的关于这件事的错误,没有已知的解决方法(这取自 Apple 的 DTS 响应)。

如果有一个 ACL 限制对它的访问并允许一个且仅一个应用程序访问该密钥,则可以删除该私钥。因此,理论上,可以更改访问对象并限制 ACL 列表,然后将其删除。

但是......不幸的是,试图操纵身份的访问对象以具有与通过钥匙串访问手动更改它时相同的 ACL 的行为并不好......

如果您确实设法限制,那么其余的就很容易了:

所以这里有一个代码片段,以防万一有人觉得它有用:

OSStatus status       = errSecSuccess;
CFTypeRef identityRef = NULL;
CFStringRef certLabel = NULL;

const char *certLabelString = "Some string identifying your certificate";
certLabel = CFStringCreateWithCString(NULL, certLabelString, kCFStringEncodingUTF8);

const void *keys[]    = { kSecClass,    kSecAttrLabel,   kSecReturnRef };
const void *values[]  = { kSecClassIdentity, certLabel, kCFBooleanTrue };
CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, 3, NULL, NULL);

// First we extract the identity out of the keychain
status = SecItemCopyMatching(query, &identityRef);
if (status != errSecSuccess)
{ 
    s_log(SecCopyErrorMessageString(status, NULL));
    CFRelease(certLabel);
    CFRelease(query);
    if (identityRef)
        CFRelease(identityRef);

    return -1;
}

CFRelease(certLabel);
CFRelease(query);

// We have obtained the identity so we can delete it
CFArrayRef itemList = CFArrayCreate(NULL, &identityRef, 1, NULL);
const void *keys2[]   = { kSecClass,  kSecMatchItemList,  kSecMatchLimit };
const void *values2[] = { kSecClassIdentity, itemList, kSecMatchLimitAll };

CFDictionaryRef dict = CFDictionaryCreate(NULL, keys2, values2, 3, NULL, NULL);
status = SecItemDelete(dict);

if (status != errSecSuccess) {
    s_log(SecCopyErrorMessageString(status, NULL));
    CFRelease(dict);
    CFRelease(itemList);
    CFRelease(identityRef);
    return -2;
}
于 2013-10-28T09:44:59.193 回答