3

我试图按照苹果文档的处理客户端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. 如何存储并检索它?

上面的链接是关于'获取和使用持久性钥匙串引用',这对我来说非常混乱。

它还谈论'在钥匙串中查找证书',但它提到使用证书的名称来查找它。我不确定'姓名'的来源。

回答

2

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

+0

谢谢!我一直试图保存/检索持久的引用/从NSUserDefaults没有运气。想知道如果我可以写到NSUserDefaults,如果是的话,如果我做得正确。 – lostintranslation

+0

我会建议不要在NSUserDefaults中存储该引用,它只是不适合它的地方,并且可能很挑剔。只需使用[-writeToFile:atomically:](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html#//apple_ref/occ/instm/NSData/writeToFile:原子:)方法 – RyanR