我正在尝试访问https协议可用的Web服务.最初我得到以下错误:

NSURLSession/NSURLConnection HTTP load Failed (kcfStreamErrorDomainSSL,-9802)
errorAn SSL error has occurred and a secure connection to the server cannot be made.

我通过在我的info.plist中添加以下内容来修复它:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>xx.xx.xxx.xxx</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

但是现在我正在连接到DIDFinishLoading代理方法中作为html响应:

400错误请求

错误的请求

您的浏览器发送了此服务器无法理解的请求.

我正在使用以下设置与服务器的信任:

func connection(connection: NSURLConnection,canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool{
    return true
}
func connection(connection: NSURLConnection,willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){
    print("willSendRequestForAuthenticationChallenge")

    let protectionSpace:NSURLProtectionSpace = challenge.protectionSpace
    let sender: NSurlauthenticationchallengesender? = challenge.sender

    if(protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust){
        let trust:SecTrustRef = challenge.protectionSpace.serverTrust!
        let credential:NSURLCredential = NSURLCredential.init(forTrust: trust)
        sender?.useCredential(credential,forAuthenticationChallenge: challenge)
    }
    else{
        sender?.performDefaultHandlingForAuthenticationChallenge!(challenge)
    }
}

有人可以帮我找出问题吗?

UPDATE1:
服务器日志显示以下错误:

Hostname xx.xx.xxx.xx provided via SNI and hostname my_secured_host_name provided via HTTP are different

如何在SNI中添加主机名?

UPDATE2:
由于服务已经是https,所以我已经从info.plist中删除了通过http的密钥

UPDATE3:
当我尝试使用openssl as

openssl s_client -showcerts -connect xx.xx.xxx.xxx:443

但我得到以下错误:

CONNECTED(00000003) 8012:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-52.40.1/src/ssl/s23_lib.c:185

UPDATE4:
更改了Info.plist以执行以下操作:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>xx.xx.xxx.xxx</key>
        <dict>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>

仍然收到以下错误:

NSURLSession/NSURLConnection HTTP load Failed (kcfStreamErrorDomainSSL,-9802)
errorAn SSL error has occurred and a secure connection to the server cannot be made.

问候
潘卡

解决方法

在其他答案和评论中已经解决的ATS问题之上,您似乎试图通过其IP地址连接到SSL服务器.
以下参考可能是有用的(我从苹果的iOS开发库中逐字引用):

To override the hostname (to allow a certificate for one specific site
to work for another specific site,or to allow a certificate to work
when you connected to a host by its IP address
),you must replace
the policy object that the trust policy uses to determine how to
interpret the certificate. To do this,first create a new TLS policy
object for the desired hostname. Then create an array containing that
policy. Finally,tell the trust object to use that array for future
evaluation of trust.

SecTrustRef changeHostForTrust(SecTrustRef trust)
{
        CFMutableArrayRef newTrustPolicies = CFArrayCreateMutable(
                kcfAllocatorDefault,&kcfTypeArrayCallBacks);

        SecPolicyRef sslPolicy = SecPolicyCreateSSL(true,CFSTR("www.example.com"));

        CFArrayAppendValue(newTrustPolicies,sslPolicy);

#ifdef MAC_BACKWARDS_COMPATIBILITY
        /* This technique works in OS X (v10.5 and later) */

        SecTrustSetPolicies(trust,newTrustPolicies);
        CFRelease(oldTrustPolicies);

        return trust;
#else
        /* This technique works in iOS 2 and later,or
           OS X v10.7 and later */

        CFMutableArrayRef certificates = CFArrayCreateMutable(
                kcfAllocatorDefault,&kcfTypeArrayCallBacks);

        /* copy the certificates from the original trust object */
        CFIndex count = SecTrustGetCertificateCount(trust);
        CFIndex i=0;
        for (i = 0; i < count; i++) {
                SecCertificateRef item = SecTrustGetCertificateAtIndex(trust,i);
                CFArrayAppendValue(certificates,item);
        }

        /* Create a new trust object */
        SecTrustRef newtrust = NULL;
        if (SecTrustCreateWithCertificates(certificates,newTrustPolicies,&newtrust) != errSecSuccess) {
                /* Probably a good spot to log something. */

                return NULL;
        }

        return newtrust;
#endif
}

资料来源:iOS Developer Library — Overriding TLS Chain Validation Correctly — Manipulating Trust Objects

请注意,在同一页面上,您可以找到处理自签名SSL证书的其他代码段,以防您处理此类证书.

要在Swift项目中使用此功能,请将新的C文件添加到您的项目(File .. New .. File .. iOS / Source / C_File),例如mysectrust.c和相应的头mysectrust.h(如果XCode要求你创建一个桥接头,说是)

mysectrust.h

#ifndef mysectrust_h
#define mysectrust_h

#include <Security/Security.h>

SecTrustRef changeHostForTrust(SecTrustRef trust);

#endif /* mysectrust_h */

mysectrust.c

#include "mysectrust.h"

SecTrustRef changeHostForTrust(SecTrustRef trust)
{
    CFMutableArrayRef newTrustPolicies = CFArrayCreateMutable(
                                                              kcfAllocatorDefault,&kcfTypeArrayCallBacks);

    SecPolicyRef sslPolicy = SecPolicyCreateSSL(true,CFSTR("www.example.com"));

    CFArrayAppendValue(newTrustPolicies,sslPolicy);

#ifdef MAC_BACKWARDS_COMPATIBILITY
    /* This technique works in OS X (v10.5 and later) */

    SecTrustSetPolicies(trust,newTrustPolicies);
    CFRelease(oldTrustPolicies);

    return trust;
#else
    /* This technique works in iOS 2 and later,or
     OS X v10.7 and later */

    CFMutableArrayRef certificates = CFArrayCreateMutable(
                                                          kcfAllocatorDefault,&kcfTypeArrayCallBacks);

    /* copy the certificates from the original trust object */
    CFIndex count = SecTrustGetCertificateCount(trust);
    CFIndex i=0;
    for (i = 0; i < count; i++) {
        SecCertificateRef item = SecTrustGetCertificateAtIndex(trust,i);
        CFArrayAppendValue(certificates,item);
    }

    /* Create a new trust object */
    SecTrustRef newtrust = NULL;
    if (SecTrustCreateWithCertificates(certificates,&newtrust) != errSecSuccess) {
        /* Probably a good spot to log something. */

        return NULL;
    }

    return newtrust;
#endif
}

当然,请使用您的主机名替换上述代码中的www.example.com.

然后,在Xcode项目projectname-Bridging-Header.h中找到桥接头,并附加以下行:

#import "mysectrust.h"

现在你可以从Swift调用这个函数,例如:

func whatever(trust: SecTrustRef){

    let newTrust = changeHostForTrust(trust) // call to C function
    ...
}

无法从iOS访问https服务的更多相关文章

  1. PhoneGap / iOS上的SQLite数据库 – 超过5mb可能

    我误解了什么吗?Phonegap中的sqlitedbs真的有5mb的限制吗?我正在使用Phonegap1.2和iOS5.解决方法您可以使用带有phonegap插件的原生sqliteDB,您将没有任何限制.在iOS5.1中,Websql被认为是可以随时删除的临时数据…

  2. ios – 使用带有NodeJs HTTPS的certificates.cer

    我为IOS推送通知生成了一个.cer文件,我希望将它与NodeJSHTTPS模块一起使用.我发现HTTPS模块的唯一例子是使用.pem和.sfx文件,而不是.cer:有解决方案吗解决方法.cer文件可以使用两种不同的格式进行编码:PEM和DER.如果您的文件使用PEM格式编码,您可以像使用任何其他.pem文件一样使用它(有关详细信息,请参见Node.jsdocumentation):如果您的文件使

  3. ios – CFNetwork内部错误:URLConnectionLoader.cpp:289

    当我在一段时间后打开我的应用程序时,我收到了日志:440:CFNetworkinternalerror(0xc01a:/buildroot/Library/Caches/com.apple.xbs/Sources/CFNetwork/CFNetwork-758.4.3/Loading/URLConnectionLoader.cpp:289)它从未出现在过去.我的项目使用网络库AFNetworkin

  4. ios – 使用大写符号在字符串swift中获取URL的正则表达式

    我尝试在文本中获取URL.所以,在此之前,我使用了这样一个表达式:但是当用户输入带有大写符号的URL时(例如Http://Google.com,它与它不匹配)我遇到了问题.我试过了:但什么都没发生.解决方法您可以使用正则表达式中的i内联标志关闭区分大小写,有关可用正则表达式功能的详细信息,请参阅FoundationFrameworkReference.(?ismwx-ismwx)Flagsetti

  5. ios – xcode在更新可可豆荚后出现体系结构错误的重复符号

    编辑:执行下面显示的解决方案后,我的项目只编译iPadAir,我不能再存档,我仍然得到相同的错误…

  6. ios – UIWebView中的WebSQL / SQLite数据库的最大大小(phonegap)

    我知道一般来说,Web应用程序的本地存储空间有5MB的限制.本地网页浏览应用程式是否也有这个限制?

  7. ios – 我可以使用自签名SSL证书服务器在空中部署企业应用吗?

    iOS7.1之后,如果我们要通过空中部署我们的Enterprise应用程序,则manifest.plist文件的URL必须是HTTPS.例如:在我的服务器中,我使用自签名SSL证书.当我点击iPhone上的URL时,它表示无法连接到并记录典型的所以,我想知道我是否可以使用自签名SSL证书?如果可以,我如何解决我遇到的问题的问题?

  8. ios – 如何使用YouTube API V3?

    我想知道如何在iOS应用中使用新的YouTubeAPI(第3版),但我不知道如何做.我做了很多关于它的研究,但是我发现所有的例子和老API的代码,所以它们是无效的.现在,我明白了,使用新的API你必须在Google开发者控制台中创建一个项目…使用API2很简单它…

  9. 如何在iOS Couchbase Mobile上使用HTTPS复制?

    我正在使用iOSCouchbaseMobile在iPad上使用一个couchdb服务器,它使用复制与服务器进行同步.cloudant使用HTTPS,当我尝试在iPad上复制时,我只是被错误地垃圾邮件发送.这是一个已知的问题,如thisFAQarticle所示.它建议使用1.0.2修复问题,但是如何知道我是否在ErlangR14上运行?

  10. ios – 有没有人使用UIWebView找到一种使用无效服务器证书加载HTTPS页面的方法?

    如果用户尝试在MobileSafari中加载https网页,并且服务器的证书验证检查失败(已过期,撤销,自签名等),则显示用户将显示一条警告消息,并询问他们是否要继续或不.类似地,NSURLConnection提供了实施者首先决定如何检查证书的能力,然后在失败的情况下决定如何执行,因此在这种情况下也可以向用户显示警告并为他们提供继续加载的机会页面还是不.但是,当在UIWebView中加载https

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部