我正在开发一个 iOS5 应用程序,它将促进两个用户之间的移动支付。作为支付过程的一部分,发送者和接收者需要与服务器进行通信。当连接时发起身份验证质询时,服务器要求双方出示他们的身份。
目前,我通过在我的代码中使用以下两种方法对证书过程进行了硬编码:
NSURLConnection 委托didReceiveAuthenticationChallenge
(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge
{
NSLog(@"Authentication challenge");
// Load Certificate
NSString *path = [[NSBundle mainBundle] pathForResource:@"PKCS12" ofType:@"p12"];
NSData *p12data = [NSData dataWithContentsOfFile:path];
CFDataRef inP12data = (__bridge CFDataRef)p12data;
SecIdentityRef myIdentity;
SecTrustRef myTrust;
extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);
SecCertificateRef myCertificate;
SecIdentityCopyCertificate(myIdentity, &myCertificate);
const void *certs[] = { myCertificate };
CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
C 方法extractIdentityAndTrust
OSStatus extractIdentityAndTrust(CFDataRef inP12data, SecIdentityRef *identity, SecTrustRef *trust)
{
OSStatus securityError = errSecSuccess;
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);
securityError = SecPKCS12Import(inP12data, options, &items);
if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
*trust = (SecTrustRef)tempTrust;
}
if (options) {
CFRelease(options);
}
return securityError;
}
我已经多次测试了这段代码并且成功了。现在我正在尝试继续并允许存储适当的身份,然后从应用程序的钥匙串中检索。我的目标是允许用户通过 iTunes 文件共享或 Dropbox 导入他们的 P12 文件并将它们保存到钥匙串中。
我查看了 Apple 关于获取和使用持久钥匙串引用的文档,但无法弄清楚如何导入身份。他们的代码让我有点困惑,因为他们使用未声明的变量/引用(特别是
&persistent_ref
多变的)。如果有人可以帮助破译它,那将不胜感激。
TL;DR:如何将 P12 文件的内容保存到我的 iOS5 应用程序的钥匙串中并稍后检索它以移交给 NSURLConnection didReceiveAuthenticationChallenge 方法?