【问题标题】:NSURLCredentialStorage and client certificate authenticationNSURLCredentialStorage 和客户端证书认证
【发布时间】:2010-11-12 12:59:28
【问题描述】:

根据我在 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 的发件人)然后使用更高级别的类访问我真正需要的东西。

【问题讨论】:

  • 我有一个问题:“extractIdentityAndTrust”是在哪里声明的?那是你的方法吗?还是它包含在图书馆中?我收到一个链接错误,说它找不到该方法。
  • 这是我的代码中定义的方法。如果您在 iOS 文档中查找名称,您会发现使用该方法的示例代码。

标签: iphone objective-c cocoa-touch https nsurlcredential


【解决方案1】:

似乎已知问题 NSURLCredentialStorage 仅适用于用户名和密码 NSURLCredentials(不支持证书)。不幸的是,文档没有提及这一点。

【讨论】:

  • 证书根本不起作用?你在哪里读到的?能给个链接吗?
  • 是的,请告诉我们您从何处获得此信息。谢谢!
  • 这记录在 AdvancedURLConnections 示例代码的 README 文件中。当前链接(Apple 将通过他们的双周“中断所有文档链接”脚本中断该链接):developer.apple.com/library/ios/#samplecode/…
  • @n8gray 我遇到了几乎相同的崩溃,所以我检查了文档以查看,我没有找到任何 NSURCredentials 不支持证书的地方。
  • @NulledPointer:对不起,我希望我能留下更多关于我的意思的细节。我无法弄清楚我链接的文档中提到的那个限制。
猜你喜欢
  • 2015-09-06
  • 2010-11-30
  • 2012-09-04
  • 2013-08-04
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
相关资源
最近更新 更多