• AFNetwork ATS 网络层改造


    最近一直做项目的ATS改造,期间遇到了种种问题,各种坑都记录下来,

    比如iOS版本、afnetwork版本、证书(是否为自签证书)、域名验证、TLS版本等等,我们项目更复杂,还使用了域名到IP映射的路由表策略,在验证自签证书的时候各种配置host,这种需求在文章里就不赘述了,有相似需求的可以私下讨论:

    有描述不对的地方,欢迎大神指正!

    先鬼扯点儿小背景,不喜请略过黄色部分:)

    关于ATS,简单说就是app使用的网络请求都必须走https,iOS9以后,此设置默认开启,项目中所有的http请求直接被系统block了,

    当然会有一些例外,可以在info.plist配置第三方域名时使用,如下:

    • NSAllowsArbitraryLoads  设置app禁用ATS,将在2017年1月1日后要求不能禁用

    • NSAllowsArbitraryLoadsInMedia  可以使用AVFoundation播放音视频不使用https

    • NSAllowsArbitraryLoadsInWebContent 可以在内置浏览器(WKWebView、UIWebView)中使用普通http请求

    • NSExceptionAllowsInsecureHTTPLoads 可以设置域名使用http请求或者没有证书、使用自签证书、证书过期、证书不匹配等等不安全请求

    • NSExceptionMinimumTLSVersion      可以设置一些https服务协商的TLS版本低于1.2

    具体的配置可以参考官方文档: 

    https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW58

    按照苹果官方的说法,对证书、域名、IP都有严格的要求,这些在配置服务器证书时都要注意

    比如证书:

    The X.509 digital server certificate must meet at least one of the following trust requirements:

    • Issued by a certificate authority (CA) whose root certificate is incorporated into the operating system

    • Issued by a trusted root CA and installed by the user or a system administrator

    即要求证书要么是正规CA颁发机构颁发的,根证书集成在系统中;要么是被用户手动安装到系统中。而且证书必须得是至少使用SHA-256加密算法

    其次,TLS version must be TLS 1.2

    加密方式也有要求:AES-128 or AES-256 等等等等

    关于ATS的限制范围,苹果是这么说的:

    ATS 只适用于host name,对下列情况不会限制:

    • IP地址(关于这一点,苹果系统在iOS9和10表现不一致,启用ATS后,在iOS10上,使用IP地址是不被限制的,但是在iOS9上会被block)

    • 非法host names(有谁知道什么是非法的么?)

    • 本地服务,如local域名

    如果使用上述说的非法host name 或者本地服务,请设置NSAllowsLocalNetworking key to YES.



    进入正题,客户端 AFNetwork适配:

    关于网络层,大部分app都是用了AFNetwork作为依赖库实现,这里就从AFNetwork开始:

    其实改造https的时候可以先不用启用ATS,改造完以后再启用就行。

    AFNetwork针对https封装了证书、域名验证的逻辑,主要集中在AFSecurityPolicy,先从最简单的说,

    正规CA证书:

    如果使用的CA证书是从正规机构购买,那么配置就比较简单:

    使用以上设置,就完成了https 功能的支持。

    关于配置项,AFSecurityPolicy使用默认的安全策略,不允许非法证书(一般是自签证书),强制要求验证域名,

    当然这些设置也是默认设置,直接省略后两行代码也可。

    自签证书: 

     如果使用自签证书,就需要走第二套方案:(让用户把证书安装到手机这招就算了,可行性几乎为0,除非你的app跟12306一样牛逼)

    首先需要把证书cer文件导入到app中,剩下的工作,AFNetwork会帮你搞定,它会自动扫描bundle中的cer文件,并制作证书信任锚点,

    比CA证书多一步导入文件,即可

    下面简单聊聊AFNetwork 的验证机制吧

    关于这一点,我在看AFNetwork源码时有个疑问,它在扫描bundle时用的[NSBundle bundleForClass:[self class]],

    而不是用的[NSBundle mainBundle],我在测试过程中遇到过一次前者返回的bundle为AFNetwork的bundle,所以读取不到cer文件,这样的话引入到工程中的cer文件肯定扫描不到吧。。。,有很多导入cer文件时手动读取的方式:如下:

     //创建证书data
            NSData*certData =[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HTTPS" ofType:@"cer"]];
            SecCertificateRef rootcert = SecCertificateCreateWithData(kCFAllocatorDefault,CFBridgingRetain(certData));
            const void *array[1] = { rootcert };
            certs = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks);
    

     anyway,无论是AFNetwork自动扫描还是手动导入,最终目的都是验证证书

    AFNetwork其实也是使用系统验证证书链的方式,首先将服务器返回的证书信息添加到验证策略:

    然后使用系统方式验证证书链:

     以上就通过了证书验证,接下来还有进行域名验证,

     

    以上主要是将app中的证书和域名进行验证

  • 相关阅读:
    Node.js EventEmitter
    Node.js 事件循环
    Node.js 回调函数(阻塞与非阻塞)
    Node.js REPL(交互式解释器)
    NPM使用介绍
    H5表单验证特性(杂七杂八知识点)
    HTML5存储之indexedDB
    本地存储localStorage和sessionStorage
    高德地图API实例--移动端婚礼请帖
    高德地图API之DOM事件+自定义事件
  • 原文地址:https://www.cnblogs.com/v-jing/p/6008964.html
Copyright © 2020-2023  润新知