在ios钥匙串上存储证书和身份?

时间:2019-03-20 15:21:11

标签: ios objective-c certificate keychain

摘要

我有一个导入到我的应用程序中的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是否将我收到的证书还给我?

谢谢

任何对这里发生的事情的了解将不胜感激。

0 个答案:

没有答案