我正在尝试通过钥匙串API从钥匙串中删除带有配对私钥的证书。我可以轻松删除证书,但是私钥始终会被留下。如何从钥匙串中将其删除???
我已经尝试了几种方法,但是即使使用了SecKeyRef,例如,一旦我运行SecItemDelete,该函数就会返回状态为errSecSuccess的键,但是该键仍在钥匙串中!!!

非常感谢您的帮助,如果有任何示例代码,请发布。
Errrrr!真令人沮丧

谢谢..

最佳答案

好吧,这个答案有点棘手。
显然,这是一个Apple已知的bug,没有已知的解决方法(取自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;
}

关于macos - 以编程方式从钥匙串(keychain)中删除私钥(与证书匹配),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19575185/

10-11 23:08
查看更多