我有一个导入到我的应用程序中的p12文件。我想将证书及其身份保存在钥匙串上。该证书将用于通过TLS客户端证书auth与服务器进行身份验证。
我一直在努力将证书和身份保存在钥匙串中。我的理解是身份是其证书的私钥。
我一直在使用Apple的文档来帮助我,但无法正常工作。
以下代码基于Apple的文档Storing Certificates 和Storing Identities
//Storing a Certificate Identity
if(CFDictionaryContainsKey(pkcs12Contents, kSecImportItemIdentity))
{
//Grab the identity from the dictionary
SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(pkcs12Contents, kSecImportItemIdentity);
CFRetain(identity);
NSDictionary* dict = @{ (id)kSecClass: (id)kSecClassIdentity,
(id)kSecValueRef: (__bridge id)identity,
(id)kSecAttrLabel: "some_unique_tag_for_id",
};
OSStatus securityError = SecItemAdd((CFDictionaryRef)dict, NULL);
//More Code
}
//Storing the Certificate
if(CFDictionaryContainsKey(pkcs12Contents, kSecImportItemCertChain))
{
CFArrayRef certs = (CFArrayRef) CFDictionaryGetValue(pkcs12Contents, kSecImportItemCertChain);
CFRetain(certs);
SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(certs, 0);
NSDictionary* dict = @{ (id)kSecValueRef: (__bridge id)cert,
(id)kSecClass: (id)kSecClassCertificate,
(id)kSecAttrLabel: "some_unique_tag_for_cert,
};
OSStatus securityError = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
//more code
}
+(SecIdentityRef)getLoginCertIdentityFromKeyChain
{
NSDictionary *getquery = @{ (id)kSecClass: (id)kSecClassIdentity,
(id)kSecAttrLabel: (id)KEY_LOGIN_CERT_ID_TAG,
(id)kSecReturnRef: @YES,
};
SecIdentityRef identity = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)getquery,
(CFTypeRef *)&identity);
if (status != errSecSuccess)
{
if (status == errSecItemNotFound)
{
return nil;
}
// Add Error Cases Here
}
return identity;
}
+(SecCertificateRef)getLoginCertChainFromKeyChain
{
NSDictionary *getquery = @{ (id)kSecClass: (id)kSecClassCertificate,
(id)kSecAttrLabel: (id)KEY_LOGIN_CERT_TAG,
(id)kSecReturnRef: @YES,
};
SecCertificateRef cert = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)getquery,
(CFTypeRef *)&cert);
if (status != errSecSuccess)
{
}
return cert;
}
1。无法检索身份
我成功保存并检索了证书。存储身份时,我会收到一个errSecSuccess
,这意味着该身份已成功添加到钥匙串中。但是,当我尝试使用getLoginCertIdentityFromKeyChain
从钥匙串接收身份时,会收到errSecItemNotFound
。
这对我来说绝对没有意义。
2。证书已存在但尚未添加。
要解决第一个问题,我删除了(id)kSecClass:(id)kSecClassIdentity
NSDictionary* dict = @{ (id)kSecValueRef: (__bridge id)identity,
(id)kSecAttrLabel: KEY_LOGIN_CERT_ID_TAG,
};
OSStatus securityError = SecItemAdd((CFDictionaryRef)dict, NULL);
这使我能够从钥匙串中检索身份。不知道为什么会起作用,但是会起作用。现在的问题是,当我尝试保存证书时,我收到了errSecDuplicateItem
。为什么已经保存?我确保已从钥匙串中删除了所有内容。
当我尝试使用getLoginCertChainFromKeyChain
方法检索“已保存”的证书时,它变得很奇怪,我收到了errSecItemNotFound
。
我对这个问题的猜测是证书与身份标签一起存储在下面吗?我确认了这一点,但我仍然不知道为什么。 Apple文档在解释正在发生的事情上做得很糟糕。
3。 SecIdentityCopyCertificate说明
最后,这是更多的问题。当我使用身份标签接收证书时,SecIdentityCopyCertificate
是否将我收到的证书还给我?
任何对这里发生的事情的了解将不胜感激。