我正在尝试通过钥匙串API从钥匙串中删除带有配对私钥的证书。我可以轻松删除证书,但私钥总是被遗忘。如何从钥匙串中删除它??? 我已经尝试了几种方法,但即使手持SecKeyRef,一旦我运行SecItemDelete(例如),该函数返回状态为errSecSuccess但键仍然存在于钥匙串中!!!
非常感谢任何帮助,如果有任何示例代码请发布。 Errrrr!这太令人沮丧......
谢谢..
答案 0 :(得分:0)
嗯,这个问题的答案有点棘手.... 显然,Apple有一个关于此事的已知错误,没有已知的解决方法(这取自Apple的DTS响应)。
如果ACL限制对其的访问并允许一个且仅一个应用程序访问密钥,则可以删除私钥。 因此,从理论上讲,可以更改访问对象并限制ACL列表,然后将其删除。
但是......不幸的是,试图操纵身份的访问对象以获得与通过Keychain Access手动更改它时相同的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;
}