iOS适配HTTPS

作者: 某天天 | 来源:发表于2018-04-18 16:33 被阅读136次

    一切为了迎合苹果

    在WWDC 2016开发者大会上,苹果宣布了一个最后期限:到2017年1月1日 App Store中的所有应用都必须启用 App Transport Security安全功能。App Transport Security(ATS)是苹果在iOS 9中引入的一项隐私保护功能,屏蔽明文HTTP资源加载,连接必须经过更安全的HTTPS。苹果目前允许开发者暂时关闭ATS,可以继续使用HTTP连接,但到年底所有官方商店的应用都必须强制性使用ATS。但如果2017年1月1日起您仍一意孤行那么在Apple Store中您的App将不能被用户下载使用。

    兼容HTTP

    新特性要求App内访问的网络必须使用HTTPS协议。
    但是现在公司的项目使用的是HTTP协议,使用私有加密方式保证数据安全。现在也不能马上改成HTTPS协议传输,需要兼容下HTTP。
    网络请求报错:The resource could not be loaded because the App Transport Security policy require:

    所以先兼容下http:

    1. Info.plist中添加NSAppTransportSecurity类型Dictionary
    2. NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES
    3. 为了适配webView中的http链接:在NSAppTransportSecurity下添加Allow Arbitrary Loads in Web Content类型Boolean,值设为YES

    适配HTTPS

    iOS开发者来说,需要尽早解决HTTPS请求的问题。

    发送HTTPS请求信任SSL证书和自签名证书,分为三种情况:

    1. (较少的公司)如果你的app服务端安装的是SLL颁发的CA,可以使用系统方法直接实现信任SSL证书,关于Apple对SSL证书的要求请参考:苹果官方文档CertKeyTrustProgGuide
      示例代码:
    NSURL *URL = [NSURL URLWithString:URLString];
     NSURLRequest *request = [[NSURLRequest alloc] initWithURL:URL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
        //创建同步连接
     NSError *error = nil;
     NSData *receivedData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error]; 
     NSString *receivedInfo = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
    
    1. (大部分公司)基于AFNetWorking的SSL特定服务器证书信任处理,使用自签名证书认证,重写AFNetWorking的customSecurityPolicy方法。

    验证证书步骤:

    1. 从服务器要来.crt格式的证书,然后用Mac钥匙串打开,然后导出 .cer格式的证书
    • .cer证书导入程序的 中。
    • 验证证书的代码:
    /**
     https证书验证
     */
    +(AFSecurityPolicy*)customSecurityPolicy
    {
        // /先导入证书
        NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"cer"];//证书的路径
        NSData *certData = [NSData dataWithContentsOfFile:cerPath];
        // AFSSLPinningModeCertificate 使用证书验证模式 (AFSSLPinningModeCertificate是证书所有字段都一样才通过认证,AFSSLPinningModePublicKey只认证公钥那一段,AFSSLPinningModeCertificate更安全。但是单向认证不能防止“中间人攻击”)
        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
        // allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
        // 如果是需要验证自建证书,需要设置为YES
        securityPolicy.allowInvalidCertificates = YES;
        //validatesDomainName 是否需要验证域名,默认为YES;
        //假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
        //置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
        //如置为NO,建议自己添加对应域名的校验逻辑。
        securityPolicy.validatesDomainName = NO;
        securityPolicy.pinnedCertificates = (NSSet *)@[certData];
        return securityPolicy;
    }
    

    其中的cerPath就是app bundle中证书路径,certificate为证书名称的宏,仅支持cer格式,securityPolicy的相关配置尤为重要,请仔细阅读customSecurityPolicy方法并根据实际情况设置其属性。

    这样,就能够在AFNetWorking的基础上使用HTTPS协议访问特定服务器,但是不能信任根证书的CA文件,因此这种方式存在风险,读取pinnedCertificates中的证书数组的时候有可能失败,如果证书不符合,certData就会为nil。

    • 在发送请求时候 加上这行代码,https ssl 验证。
    //    [[AFHTTPSessionManager manager] setSecurityPolicy:[JYAFNetworkingManager customSecurityPolicy]];
    
    1. 更改系统方法,发送异步NSURLConnection请求。
      这种方式用的很少就不多介绍了有新区可以自行搜索;

    大部分可以参考:
    http://www.jianshu.com/p/f312a84a944c
    http://www.jianshu.com/p/6b9c8bd5005a
    http://www.jianshu.com/p/b03ae4a1a2d3

    相关文章

      网友评论

        本文标题:iOS适配HTTPS

        本文链接:https://www.haomeiwen.com/subject/ksxbkftx.html