将钥匙链中的.p12证书存储在稍后使用

我想在这里跟随苹果文档处理客户端p12证书:

https://developer.apple.com/library/ios/documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-SW13

我已成功从文件系统加载.p12证书:

- (SecIdentityRef)getClientCertificate:(NSString *) certificatePath { SecIdentityRef identity = nil; NSData *PKCS12Data = [NSData dataWithContentsOfFile:certificatePath]; CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data; CFStringRef password = CFSTR("password"); const void *keys[] = { kSecImportExportPassphrase }; const void *values[] = { password }; CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items); CFRelease(options); CFRelease(password); if (securityError == errSecSuccess) { NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items)); CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0); identity = (SecIdentityRef) CFDictionaryGetValue(identityDict, kSecImportItemIdentity); } else { NSLog(@"Error opening Certificate."); } return identity; } 

然后我得到这个身份的证书:

 - (CFArrayRef)getCertificate:(SecIdentityRef) identity { SecCertificateRef certificate = nil; SecIdentityCopyCertificate(identity, &certificate); SecCertificateRef certs[1] = { certificate }; CFArrayRef array = CFArrayCreate(NULL, (const void **) certs, 1, NULL); SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); SecTrustRef myTrust; OSStatus status = SecTrustCreateWithCertificates(array, myPolicy, &myTrust); if (status == noErr) { NSLog(@"No Err creating certificate"); } else { NSLog(@"Possible Err Creating certificate"); } return array; } 

但是我真正想要做的是将证书(或身份)存储在我的应用程序钥匙串中,所以我没有从文件系统中读取它。

几个问题:

  1. 我应该存储哪个? 证书或身份?
  2. 我如何存储和检索?

上面的链接谈到“获取和使用持久性钥匙链参考”这是非常令我困惑的。

它还谈到了“在钥匙串中查找证书”,但它提到使用证书的名称来查找它。 我不确定这个名字来自哪里。

我想不出有什么好的理由将证书存储在钥匙串中,虽然我相信可能会有一些。 我只在钥匙串中存储身份(这是私钥部分)。 为了更容易地find钥匙串中的身份,您生成一个持久的引用(见链接列表2-3),然后将该持久引用保存在您的应用程序的文件系统中。 持久性引用只是一个CFDataRef,你可以免费桥接到NSData对象,然后轻松保存/加载。 当你想要encryption/不pipe什么的私钥的时候,你使用这个持久的引用来加载钥匙链中的身份(见链接列表2-4)。 我会为你发布一些代码,但是我正在重build我的开发机器,现在还没有安装Xcode。