Objective-C /可可:我如何接受错误的服务器证书?
我试图使用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连接以获得不受信任的证书?