Objective-C /可可:我如何接受错误的服务器证书?

时间:2020-03-05 18:40:32  来源:igfitidea点击:

我试图使用NSURLRequest访问具有过期证书的网站。发送请求时,将使用以下信息调用我的connection:didFailWithError委托方法:

-1203, NSURLErrorDomain, bad server certificate

我的搜索仅提供了一种解决方案:NSURLRequest中的隐藏类方法:

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:myHost];

但是,出于明显的原因,我不想在生产应用程序中使用私有API。

有什么建议怎么办?我是否需要使用CFNetwork API,如果有,请使用两个问题:

  • 我可以使用任何示例代码入门吗?我还没有在网上找到任何东西。
  • 如果我为此使用CFNetwork,是否必须完全放弃NSURL?

编辑:

iPhone OS 3.0引入了一种受支持的方法来执行此操作。此处有更多详细信息:如何使用NSURLConnection与SSL连接以获得不受信任的证书?

解决方案

回答

我遇到了与开发SOAP客户端相同的问题,并且开发服务器具有"本地"证书。我什至没有使用NSURL来解决问题,因为我没有使用NSURL,但是(文献记载不清,显然被遗弃的)WS方法决定暂时(内部)使用非SSL联系。

话虽如此,但浮现在脑海的问题是,如果我们不愿意在生产应用程序中使用私有API,我们是否应该允许访问带有躲避证书的网站?

我将引用Jens Alfke的话:

That's not just a theoretical security problem. Something

  like 25% of public DNS servers have been compromised, according to

  recent reports, and can direct users to phishing/malware/ad sites even

  if they enter the domain name properly. The only thing protecting you

  from that is SSL certificate checking.

回答

是否可以创建自签名证书并将自定义证书颁发机构添加到受信任的CA?我不太确定这在iPhone上如何工作,但是我认为在Mac OS X上我们可以将它们添加到钥匙串中。

我们可能对此帖子也有兴趣Re:如何处理NSURLDownload中的错误证书错误

回答

如果用于内部服务器以进行测试,为什么不将测试服务器的证书导入KeyChain并设置自定义信任设置呢?

回答

支持的方法是使用CFNetwork。我们要做的是将kCFStreamPropertySSLSettings添加到指定kCFStreamSSLValidatesCertificateChain == kCFBooleanFalse的流。下面是执行此操作的一些快速代码,减去对有效结果的检查会增加清理效果。完成此操作后,我们可以使用CFReadStreamRead()获取数据。

CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, CFSTR("http://www.apple.com"), NULL);
CFHTTPMessageRef myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), myURL, kCFHTTPVersion1_1);
CFReadStreamRef myStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest);
CFMutableDictionaryRef myDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(myDict, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
CFReadStreamSetProperty(myStream, kCFStreamPropertySSLSettings, myDict);    
CFReadStreamOpen(myStream);

回答

另一种选择是使用备用连接库。

我是AsyncSocket的忠实拥护者,它支持自签名证书

http://code.google.com/p/cocoaasyncsocket/

看一下,我认为它比标准的NSURLRequests更健壮。

回答

iPhone OS 3.0引入了一种受支持的方法,不需要较低级别的CFNetwork API。此处有更多详细信息:

如何使用NSURLConnection与SSL连接以获得不受信任的证书?