IOS开发入门iOS开发适配HTTPS详细教程
白羽 2019-04-16 来源 :网络 阅读 130 评论 0

摘要:本文将带你了解IOS开发入门iOS开发适配HTTPS详细教程,希望本文对大家学IOS有所帮助。

    本文将带你了解IOS开发入门iOS开发适配HTTPS详细教程,希望本文对大家学IOS有所帮助。


IOS开发入门iOS开发适配HTTPS详细教程


苹果官方在2017年将会强制要求使用HTTPS,当然,很多开发者可能会误解会所有在应用里面的请求都必须使用HTTPS,其实不完全是这样。苹果官方文档提高了很多细节的东西,告诉开发者如何让自己的应用适配HTTPS,本文将从原理,官方文档,以及作者的实践经验出发。详细介绍如何iOS中使用HTTS以及使用时需要注意的细节问题。
   
   HTTPS基本原理
   首先我们以网络传输的7个层来快速的弄懂HTTP和HTTPS的基本区别。
   HTTP传输:
   
   HTTPS传输:
   
   一眼就可以看出区别了吧,其实HTTPS就是在HTTP的基础上,在传输层和会话层之间了一个SSL层,简单来说都作用是负责数据的加解密,从而保证了数据都安全。
   SSL(Security Socket Layer 安全套接层)  最初1994年Netscape开发,专门用于保护Web通讯.保护浏览器和服务器之间的通信,在客户和服务器之间提供服务器鉴别、可选客户鉴别和加密通信信道。使用TCP提供一种可靠的端对端的安全服务。
   版本和历史
   1.0,不成熟 2.0,基本上解决了Web通讯的安全问题
   Microsoft公司发布了PCT(Private Communication Technology),并在IE中支持  3.0,1996年发布,增加了一些算法,修改了一些缺陷
   TLS 1.0(Transport Layer Security传输层安全协议, 也被称为SSL  3.1),1997年IETF发布了Draft,同时,Microsoft宣布放弃PCT,与Netscape一起支持TLS 1.0
   1999年,发布RFC 2246(The TLS Protocol v1.0)
   
    苹果现在要求使用的是TLS1.2。待会我会继续提到这个问题。
   
   SSL的主要功能
   客户端验证服务器 客户段与服务器选择彼此支持的算法 服务器验证客户端(可选) 使用公开密钥算法产生共享的密钥
   当然,HTTPS比较难以理解的还是它的协议,尤其是握手协议,考虑到篇幅的原因,这里不过多的讲解。
   官方相关文档解读
   App Transport Security (ATS)在iOS  9.0之后就默认开启了。也就是我吗之前请求HTTPS的时候NSAllowsArbitraryLoads这个key的值默认设置为NO了,而且这个键现在在NSAppTransportSecurity字典的第一层。
   NSAppTransportSecurity : Dictionary  {    NSAllowsArbitraryLoads :  Boolean    NSAllowsArbitraryLoadsForMedia :  Boolean    NSAllowsArbitraryLoadsInWebContent :  Boolean    NSAllowsLocalNetworking :  Boolean    NSExceptionDomains : Dictionary  {        :  Dictionary  {            NSIncludesSubdomains  : Boolean            NSExceptionAllowsInsecureHTTPLoads  :  Boolean            NSExceptionMinimumTLSVersion  :  String            NSExceptionRequiresForwardSecrecy  : Boolean   // Default value is  YES            NSRequiresCertificateTransparency  : Boolean        }    }}
   除了NSExceptionRequiresForwardSecrecy默认的值时YES。其它的默认的值都是NO。
   NSAppTransportSecurity字典分两个层级配置,前面四个
   NSAllowsArbitraryLoads,NSAllowsArbitraryLoadsForMedia,
   NSAllowsArbitraryLoadsInWebConten, NSAllowsLocalNetworking  是对整个APP全局的配置。如果我们需要对某个域名有区分的对待就需要在NSExceptionDomains里面进行相应的配置。
   NSAllowsArbitraryLoads
   设置为YES的话,就会使得除了开发者在NSExceptionDomains里面配置的域名以外所有的网络连接不受限制。
   如果你设置为YES的话,需要在提审核的时候说明这样做的原因。
   NSAllowsArbitraryLoadsForMedia
   设置为YES的话,所有在APP里面使用AV Foundation  framework加载的视频都不会被限制。如果不设置的话,就仅用于加载已加密的媒体,例如由FairPlay或安全HLS保护的文件,并且不包含个人信息。
   如果你设置为YES的话,同样也是需要在提审核的时候说明你这样做的原因。
   NSAllowsArbitraryLoadsInWebContent
   如果你设置为YES的话,系统会禁用对来自Web视图的请求的所有ATS限制,也就是你的WebView的请求不不一定需要HTTPS,APP就可以使用嵌入式浏览器来显示任意内容,但是应用的其他部分还是需要用ATS。
   如果你设置为YES的话,同样也是需要在提审核的时候说明你这样做的原因。
   NSAllowsLocalNetworking
   设置为YES的话就允许加载本地资源。
   NSExceptionDomains
   NSExceptionDomains其实是相当于NSAllowsArbitraryLoads的一个子集。后者是全局的作用,而前者主要是用于对某些域名的限制作用。他的主要作用其实就是用于们自签名的证书,具体使用细节我会在后面具体介绍。
   NSExceptionDomains字典里面各键的值意义如下。
   NSIncludesSubdomains
   默认为NO,如果设置为YES,则表示当前设置域名的所有子域名也使用同样的配置
   NSExceptionAllowsInsecureHTTPLoads
   允许不安全的HTTP请求,这里所谓的不安全,不代表改变了 Transport Layer Security  (TLS)或是事HTTPS的请求。所谓的不安全主要是因为使用自签名的证书,没有经过CA认证所以苹果并不知道是不是安全的,如果开发者允许那么苹果也允许加载。  
   设置为YES,在审核的时候你需要说明原因
   NSExceptionMinimumTLSVersion
   这个属性用于表面你的HTTPS的TLS版本,因为苹果默认是支持TLS1.2,所以如果你使用了较低的版本你你需要自己指明。
   设置为这个键后,在审核的时候你也需要说明原因。
   NSExceptionRequiresForwardSecrecy
   如果设置为NO,则允许不支持完全前向保密(PFS)的TLS密码(对于指定的域名)。  默认值为YES。关于完全正向保密,可以看这篇文章TLS完美前向保密(perfect forward secrecy)翻译。
   NSRequiresCertificateTransparency
   如果设置为YES,则对于命名域的服务器证书,需要有效的签名证书透明度的时间戳。 默认值为NO。
   以上这么多内容,对于iOS开发者来自说最重要的信息就是有五个键,如果开发者不使用默认值,则需要在审核的时候进行说明。这五个键是
   NSAllowsArbitraryLoads
   NSAllowsArbitraryLoadsForMedia
   NSAllowsArbitraryLoadsInWebContent
   NSExceptionAllowsInsecureHTTPLoads
   NSExceptionMinimumTLSVersion
   这对于嵌入了很多网页或是视频的APP来说感觉会比较麻烦一些。
   使用CA颁发证书的开发者
   如果想要简单实用,公司又壕气,那就推荐使用这种方法。就是花钱买一个CA机构颁发的证书,也可以是CA机构授权二级或是三级机构颁发的证书,国内很多的颁发证书的公司,可以直接找他们买。
   证书的算法使用RSA还是圆锥曲线(ECC)并没有太大区别,我见过的大部分是RSA算法的。
   弄好证书后,丢给后台,让他们搭建HTTPS的服务器,理论上iOS端只需要修改地址为HTTPS的地址就可以适配成功。但是还是做一些配置来保证万无一失吧。
   如果项目使用的是AFNetWorking的话。只需要如下几句代码就可以搞定。
   NSString *urlString =  @"https://www.apple.com";    AFHTTPSessionManager  *manager = [AFHTTPSessionManager  manager];    AFSecurityPolicy *securityPolicy =  [AFSecurityPolicy  policyWithPinningMode:AFSSLPinningModeNone];    [securityPolicy  setValidatesDomainName:YES];    manager.securityPolicy =  securityPolicy;    manager.responseSerializer =  [AFHTTPResponseSerializer serializer];     //  request    [manager  GET:urlString      parameters:nil        progress:nil         success:^(NSURLSessionDataTask  * _Nonnull task, id  _Nullable responseObject)  {             NSDictionary  * array = [NSJSONSerialization JSONObjectWithData:responseObject  options:NSJSONReadingMutableLeaves  error:nil];             NSLog(@"OK  === %@",array);             NSString  *htmlString = [[NSString alloc]initWithData:responseObject  encoding:NSUTF8StringEncoding];             NSLog(@"%@",htmlString);         }  failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)  {             NSLog(@"error  ==%@",error.description);         }];
   不过这里最值得关注的是AFSSLPinningModeNone,我们点进去看AF的源码的时候,就会发现这是一个枚举,主要包括了三种类型。
   enum { AFSSLPinningModeNone, AFSSLPinningModePublicKey, AFSSLPinningModeCertificate, }  `AFSSLPinningModeNone` Do  not used pinned certificates to validate  servers.  `AFSSLPinningModePublicKey` Validate host  certificates against public keys of pinned certificates.  `AFSSLPinningModeCertificate` Validate  host certificates against pinned certificates.*/
   AFSSLPinningModeNon表示不做SSL  pinning,只跟浏览器一样在系统的信任机构列表里验证服务端返回的证书。若证书是信任机构签发的就会通过,若是自己服务器生成的证书,是不会通过的。
   AFSSLPinningModeCertificate表示用证书绑定方式验证证书,需要客户端保存有服务端的证书拷贝,这里验证分两步,第一步验证证书的域名/有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。
   AFSSLPinningModePublicKey是用证书绑定方式验证,客户端要有服务端的证书拷贝,只是验证时只验证证书里的公钥,不验证证书的有效期等信息。只要公钥是正确的,就能保证通信不会被窃听,因为中间人没有私钥,无法解开通过公钥加密的数据。
   也就是如果你使用后面两种模式你的工程里面需要导入cer证书文件。这个文件的路径随意,AFNetWorking会自动替你寻找。如果你觉得不放心也可以使用下面的代码直接指定文件。
   NSData *certData = [NSData dataWithContentsOfFile:[[NSBundle  mainBundle] pathForResource:@"12306"  ofType:@"cer"]];    NSSet *cerSet  =  [NSSet  setWithObject:certData];    if(certData){        [securityPolicy  setPinnedCertificates:cerSet];    }
   这样就可以去测试看看能不能跑起来了~
   使用自签名的证书
   使用自签名的证书比使用CA的要复杂一些。国内最著名的使用自签名证书的就是12306了。我们可以看看12306的证书文件。
   首先我们需要下载它证书,对于网络上支持HTTPS的网站我们都可以通过下列方式获取相应的证书。
openssl s_client -connect kyfw.12306.cn:443 /dev/null | openssl x509  -outform DER > 12306.cer openssl s_client -connect www.apple.com:443  /dev/null | openssl x509 -outform DER > apple.cer
   执行命令后就会在当前目录下生成一个12306.cer的文件,我们把文件拷贝到Xcode里面可以查看相应的证书信息。
   
   这个SRCA是12306自己搞定一个证书机构,也是没有CA认证过的。所以也算是一个自签名证书。
   为了方便测试,我这里使用12306的证书来讲解自签证书配置。首先我不作任何配置使用如下代码测试网络能否联通
     NSString  *urlString =  @"https://kyfw.12306.cn/otn";     AFHTTPSessionManager  *manager = [AFHTTPSessionManager manager];    AFSecurityPolicy  *securityPolicy = [AFSecurityPolicy  policyWithPinningMode:AFSSLPinningModePublicKey];    [securityPolicy  setAllowInvalidCertificates:YES];    [securityPolicy  setValidatesDomainName:YES];    manager.securityPolicy =  securityPolicy;     //用于指定文件//     NSData *certData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle]  pathForResource:@"12306" ofType:@"cer"]];//     NSSet *cerSet  = [NSSet setWithObject:certData];//     if(certData){//        [securityPolicy  setPinnedCertificates:cerSet];//     }     manager.responseSerializer =  [AFHTTPResponseSerializer serializer];    [manager  GET:urlString      parameters:nil        progress:nil         success:^(NSURLSessionDataTask  * _Nonnull task, id  _Nullable responseObject)  {             NSDictionary  * array = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves  error:nil];             NSLog(@"OK  ===  %@",array);             NSString  *htmlString = [[NSString alloc]initWithData:responseObject  encoding:NSUTF8StringEncoding];             NSLog(@"%@",htmlString);         }  failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)  {             NSLog(@"error  ==%@",error.description);         }];
   可以看到结果如下
   
   我们并不能正常访问1230网站,我们使用源码的方式打开plist文件
   
   然后在里面添加如下配置
 NSAppTransportSecurity    NSExceptionDomains            

kyfw.12306.cn    

NSIncludesSubdomains                     

 NSExceptionRequiresForwardSecrecy                      

 NSExceptionAllowsInsecureHTTPLoads                        
   再次运行程序访问12306.可以看到成功加载到了数据
   
   关于这个配置文件怎么配置呢。如果不是很清楚的话,建议使用苹果提供的工具
   /usr/bin/nscurl --ats-diagnostics [--verbose] URL
   比如我测试苹果的网站(我只截取了部分信息)
   hly:Desktop  jianquan$  /usr/bin/nscurl --ats-diagnostics --verbose  https://www.apple.comStarting ATS Diagnostics Configuring ATS Info.plist  keys and displaying the result of HTTPS loads to https://www.apple.com.A test  will "PASS" if URLSession:task:didCompleteWithError: returns a nil  error

Default  ATS Secure Connection---ATS Default ConnectionATS Dictionary:{}Result :  PASS ---TLSv1.1 with PFS disabled and insecure HTTP allowedATS  Dictionary:{    NSExceptionDomains  =      {        "www.apple.com"  =          {            NSExceptionAllowsInsecureHTTPLoads  =  true;            NSExceptionMinimumTLSVersion  =  "TLSv1.1";            NSExceptionRequiresForwardSecrecy  =  false;        };    };}Result  : PASS--- ---TLSv1.0 with PFS disabled and insecure HTTP allowedATS  Dictionary:{    NSExceptionDomains  =      {        "www.apple.com"  =          {            NSExceptionAllowsInsecureHTTPLoads  =  true;            NSExceptionMinimumTLSVersion  =  "TLSv1.0";            NSExceptionRequiresForwardSecrecy  = false;        };    };}Result  : PASS---
   Result :  PASS表明我可以使用推荐的键值对来适配HTTPS。对于自己的域名我们也可以先让后台配置好HTTPS之后,然后以上方法,就能更快更好的适配了。
   对于自签的证书我们按照上面的教程配置就好。但是你会问我,BB可半天,证书在那里呢?别急下面一节我专门讲解如何生成自己的证书。
   生成自签名的证书
   我在大二的时候写过一篇文章,专门研究了数字证书的相关东西 数字证书及其简单数字签名的实现(java实现)
   首先请确保你的电脑安装了jdk,没有的话请到官网下载安装。Mac或是Windows下生成证书的方式都是一样的。java的跨平台性—。
   安装好java后,打开终端,生成相应的证书
   keytool -genkey -alias JoySeeDog -keyalg RSA -keysize 1024  -keystore  JoySeeDog -validity 365
   这里面可以配置的参数包括如下,可以根据自己需求使用。
   -alias                    要处理的条目的别名 -keyalg                 密钥算法名称 -keysize                 密钥位大小 -sigalg                 签名算法名称 -destalias             目标别名 -dname                   唯一判别名 -startdate             证书有效期开始日期/时间 -ext                       X.509 扩展 -validity                有效天数 -keypass                    密钥口令 -keystore               密钥库名称 -storepass                  密钥库口令 -storetype             密钥库类型 -providername     提供方名称 -providerclass   提供方类名 -providerarg                提供方参数 -providerpath           提供方类路径 -v                               详细输出 -protected                       通过受保护的机制的口令
   然后会提示你输入相应的信息,如下图所示
   
   然后可以使用如下命令查看相应的信息。
   keytool -list -v -keystore JoySeeDog
   相关信息如下
   
   确认证书的相关信息没有问题后,就可以导出相应的证书了。
  -rfc                             以 RFC  样式输出 -alias                    要处理的条目的别名 -file                   输出文件名 -keystore               密钥库名称 -storepass                  密钥库口令 -storetype             密钥库类型 -providername     提供方名称 -providerclass   提供方类名 -providerarg                提供方参数 -providerpath         提供方类路径 -v                               详细输出 -protected                       通过受保护的机制的口令
   
   可以看到当前目录下出现了一个JoySeeDog和一个JoySeeDog.cer文件。准确的说这个JoySeeDog文件在第一步就出现了,保存好这两个文件。以后也许会用到。
   把证书拖入Xcode,可以看到崭新的证书做好了~

  

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

X
免费获取海同IT培训资料
验证码手机号,获得海同独家IT培训资料
获取验证码
提交

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    ICP许可  沪B2-20190160

站长统计