NSURLCredentialStorage和客户端证书身份验证

问题描述:

从我在MPMoviewPlayerController的文档中看到的,NSURLCredentialStorage可以设置为NSURLConnection身份验证挑战的替代方案(这对于从URL加载资源但将NSURLConnection抽象出来的较高级类很有用不提供处理认证挑战的代表)。这似乎与在浏览器中安装证书类似,并且在某个地址需要时自动选择所需的证书。NSURLCredentialStorage和客户端证书身份验证

为了测试这一点,我建立了自己的证书颁发机构,服务器证书和客户端证书(.p12文件)。我已经建立了一个https服务器,并使用浏览器从另一台机器成功测试了客户端证书。

现在我需要将证书集成到我的iPhone应用程序中。

我已经捆绑了P12文件和应用程序启动我这样做:

NSString *thePath = [[NSBundle mainBundle] pathForResource:@"clientside" ofType:@"p12"]; 
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; 
CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;  
SecIdentityRef identity; 
SecTrustRef trust; 
extractIdentityAndTrust(inPKCS12Data, &identity, &trust); 

SecCertificateRef certificate = NULL; 
SecIdentityCopyCertificate (identity, &certificate); 

const void *certs[] = {certificate}; 
CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL); 

NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(NSArray*)certArray persistence:NSURLCredentialPersistencePermanent]; 

NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] 
             initWithHost: @"myhostname" 
             port: 443 
             protocol: @"https" 
             realm: nil 
             authenticationMethod: NSURLAuthenticationMethodClientCertificate]; 

[[NSURLCredentialStorage sharedCredentialStorage] 
setDefaultCredential: credential 
forProtectionSpace: protectionSpace]; 

的extractIdentityAndTrust功能简单复制形式的“证书,密钥和信托服务任务的iOS”文档页面(我只是用自己的密码替换了证书密码)。

从我可以告诉身份和证书加载很好。如果我在控制台中打印NSURLCredential对象,我会得到如下结果:<NSURLCredential: 0x140ea0>: (null)(我不知道这是否是一个好兆头)。

但是,当我执行setDefaultCredential时,应用程序崩溃而没有提供太多的信息。

堆栈跟踪看起来是这样的:

#0 0x350a41c8 in CFHash 
#1 0x3515180c in __CFBasicHashStandardHashKey 
#2 0x351534e4 in ___CFBasicHashFindBucket_Linear 
#3 0x350a4000 in CFBasicHashFindBucket 
#4 0x350a3ecc in CFDictionaryGetValue 
#5 0x344a0df2 in URLCredentialStorage::setDefaultCredentialForProtectionSpace 
#6 0x3446a5aa in CFURLCredentialStorageSetDefaultCredentialForProtectionSpace 
#7 0x339ec79e in -[NSURLCredentialStorage setDefaultCredential:forProtectionSpace:] 
#8 0x00002612 in -[AVPlayerExampleViewController awakeFromNib] at AVPlayerExampleViewController.m:84 

我看来像有什么在凭证不成立。

关于如何解决这个问题的任何想法?

编辑:

只是为了测试我从邮件中打开该文件安装在iPhone上的证书。我可以通过Safari通过https访问页面,但不能通过我的应用程序访问。

唯一可行的是,如果我打开一个NSURLConnection到受保护域上的任何资源,回应didReceiveAuthenticationChallenge(我在上面的代码中完全加载我的凭证,只是直接发送给N​​SURLAuthenticationChallenge的发件人)和然后使用更高级的课程访问我真正需要的东西。

+0

我有一个问题:“extractIdentityAndTrust”在哪里声明?你的方法是?还是从图书馆收录?我收到一个链接错误,说它找不到该方法。 – mtmurdock 2011-04-06 18:05:16

+0

这是我的代码中定义的方法。如果你在iOS文档中查找这个名字,你会发现这个方法的代码示例。 – 2011-04-07 06:41:29

看来这是一个已知的问题,NSURLCredentialStorage只适用于用户名密码& NSURLCredentials(证书不支持)。不幸的是,文档没有提到这一点。

+0

证书不工作?你从哪里读到的?你能提供一个链接吗? – mtmurdock 2011-04-07 14:25:11

+0

是的,请让我们知道你的信息。谢谢! – n8gray 2011-09-14 17:50:48

+1

这是在AdvancedURLConnections示例代码的自述文件中记录的。当前链接(苹果公司将与他们的双周刊“打破所有文档链接”脚本):http://developer.apple.com/library/ios/#samplecode/AdvancedURLConnections/Listings/Read_Me_About_AdvancedURLConnections_txt.html#//apple_ref/ doc/uid/DTS40009558-Read_Me_About_AdvancedURLConnections_txt -DontLinkElementID_24 – n8gray 2011-09-15 21:31:21