从我在 MPMoviewPlayerController 文档中看到的内容来看,可以将 NSURLCredentialStorage 设置为 NSURLConnection 身份验证挑战的替代方案(这对于从 URL 加载资源但抽象 NSURLConnection 并且不提供处理身份验证的委托的更高级别的类很有用挑战)。这似乎类似于在浏览器中安装证书并在某个地址需要时自动选择所需的证书。
为了测试这一点,我设置了自己的证书颁发机构、服务器证书和客户端证书(一个 .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
在我看来,凭证中没有设置一些东西。
关于如何解决这个问题的任何想法?
编辑:
只是为了测试,我通过从 Mail 中打开文件在 iPhone 上安装了证书。我可以通过 Safari 通过 https 访问页面,但不能通过我的应用程序。
唯一有效的是,如果我打开一个 NSURLConnection 到受保护域上的任何资源,响应 didReceiveAuthenticationChallenge(我在上面的代码中加载我的凭据,只是我将它直接发送到 NSURLAuthenticationChallenge 的发件人)然后访问这些东西我真的需要使用更高级别的课程。