【问题标题】:Objective-C/Cocoa: How do I accept a bad server certificate?Objective-C/Cocoa:如何接受错误的服务器证书?
【发布时间】:2010-09-06 03:04:24
【问题描述】:

使用 NSURLRequest,我正在尝试访问证书已过期的网站。当我发送请求时,我的 connection:didFailWithError 委托方法会使用以下信息调用:

-1203, NSURLErrorDomain, bad server certificate

我的搜索只找到了一个解决方案:NSURLRequest 中的隐藏类方法:

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:myHost];

但是,出于显而易见的原因,我不想在生产应用中使用私有 API。

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

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

编辑:

iPhone OS 3.0 引入了一种支持的方法来执行此操作。更多细节在这里:How to use NSURLConnection to connect with SSL for an untrusted cert?

【问题讨论】:

    标签: objective-c cocoa networking


    【解决方案1】:

    我遇到了同样的问题 - 我正在开发一个 SOAP 客户端,而开发服务器有一个“本土”证书。即使使用该方法,我也无法解决问题,因为我没有使用 NSURL,但是(记录不充分且显然已放弃)WS 方法,并暂时决定(内部)仅使用非 SSL连接。

    话虽如此,但想到的问题是,如果您不愿意在生产应用程序中使用私有 API,您是否应该允许访问带有不可靠证书的网站?

    我会引用Jens Alfke:

    这不仅仅是理论上的安全问题。东西

    称,像 25% 的公共 DNS 服务器已被入侵 最近的报告,甚至可以将用户引导至网络钓鱼/恶意软件/广告网站
    如果他们正确输入域名。唯一能保护你的东西
    从那是 SSL 证书检查。

    【讨论】:

    • 有问题的站点在我们的测试环境中,只能在内部访问。我猜网络管理员太便宜或太懒了,无法为其维护有效证书。当然,我们的生产环境有一个有效的证书。由于在生产中不会启用或不需要此证书躲避功能,因此我可以使用私有 API 仅用于测试。我仍然更喜欢以“正确”的方式来做,因为如果私有 API 被拉出,我会回到第一方。
    【解决方案2】:

    您能否创建自签名证书并将您的自定义证书颁发机构添加到受信任的 CA?我不太确定这在 iPhone 上是如何工作的,但我假设在 Mac OS X 上你会将这些添加到钥匙串中。

    您可能也对此帖子感兴趣Re: How to handle bad certificate error in NSURLDownload

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        执行此操作的受支持方式需要使用 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);
        

        【讨论】:

          【解决方案5】:

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

          我是 AsyncSocket 的忠实粉丝,它支持自签名证书

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

          看一下,我认为它比标准的 NSURLRequests 更强大。

          【讨论】:

            【解决方案6】:

            iPhone OS 3.0 引入了一种支持的方式来执行此操作,不需要较低级别的 CFNetwork API。更多细节在这里:

            How to use NSURLConnection to connect with SSL for an untrusted cert?

            【讨论】:

              猜你喜欢
              • 2022-07-20
              • 2021-10-03
              • 2012-02-26
              • 1970-01-01
              • 2012-09-24
              • 2014-04-10
              • 2019-12-23
              • 1970-01-01
              • 2018-07-19
              相关资源
              最近更新 更多