html5中文学习网

您的位置: 首页 > ios » 正文

iOS开发:服务器到客户端对ATS的适配_IOS开发

[ ] 已经帮助:人解决问题

   一、简单谈谈ATS(App Transport Security)RB9HTML5中文学习网 - HTML5先行者学习网

  ATS(App Transport Security)是为了提高App与服务器之间安全传输数据一个特性,这个特性从iOS9和OSX10.11开始出现,它默认需要满足以下几个条件:RB9HTML5中文学习网 - HTML5先行者学习网

  服务器TLS版本至少是1.2版本RB9HTML5中文学习网 - HTML5先行者学习网

  连接加密只允许几种先进的加密RB9HTML5中文学习网 - HTML5先行者学习网

  证书必须使用SHA256或者更好的哈希算法进行签名,要么是2048位或者更长的RSA密钥,要么就是256位或更长的ECC密钥。RB9HTML5中文学习网 - HTML5先行者学习网

  如果想了解哪几种先进的加密是被允许的,详情请见官方文档App Transport Security TechnoteRB9HTML5中文学习网 - HTML5先行者学习网

  二、搭建HTTPS服务器RB9HTML5中文学习网 - HTML5先行者学习网

  搭建HTTPS服务器有两种方式,一种是创建证书请求,然后到权威机构认证,随之配置到服务器;另外一种是自建证书,然后配置给服务器。第一种方式搭建的HTTPS服务器当然是最优的了,建立网站的话,直接就会被信任,而作为移动端app的服务器时,也不需要为ATS做过多的适配。虽然说权威的机构认证都是需要钱的,但是如今也不乏存在免费的第三方认证机构;第二种方式搭建的HTTPS服务器,对于网站来说完全不可行,用户打开时直接弹出一个警告提醒,说这是一个不受信任的网站,让用户是否继续,体验很差,而且让用户感觉网站不安全。对于移动端来说,在iOS9出现之前,这个没什么问题,但是在iOS9出来之后,第二种方式是通不过ATS特性,需要将NSAllowsArbitraryLoads设置为YES才行。所以,我推荐使用第一种方式搭建HTTPS服务器。RB9HTML5中文学习网 - HTML5先行者学习网

  下面,咱们来说说这两种方式都如何进行操作。RB9HTML5中文学习网 - HTML5先行者学习网

  第一种、使用CA机构认证的证书搭建HTTPS服务器RB9HTML5中文学习网 - HTML5先行者学习网

  1、创建证书请求,并提交给CA机构认证RB9HTML5中文学习网 - HTML5先行者学习网

  #成私钥RB9HTML5中文学习网 - HTML5先行者学习网

  openssl genrsa -des3 -out private.key 2048RB9HTML5中文学习网 - HTML5先行者学习网

  #生成服务器的私钥,去除密钥口令RB9HTML5中文学习网 - HTML5先行者学习网

  openssl rsa -in private.key -out server.keyRB9HTML5中文学习网 - HTML5先行者学习网

  #生成证书请求RB9HTML5中文学习网 - HTML5先行者学习网

  openssl req -new -key private.key -out server.csrRB9HTML5中文学习网 - HTML5先行者学习网

  将生成server.csr提交给CA机构,CA机构对它进行签名之后,然后会生成签名后的根证书和服务器证书发送给你,这个时候的证书就是CA认证之后的证书。我们这里将根证书和服务器证书分别改名为ca.crt和serve.crt。RB9HTML5中文学习网 - HTML5先行者学习网

  2、配置Apache服务器RB9HTML5中文学习网 - HTML5先行者学习网

  将ca.crt、server.key、server.crt上传到阿里云服务器,使用SSH登陆进入这三个文件的目录,执行下面命令 mkdir ssl cp server.crt /alidata/server/httpd/conf/ssl/server.crt cp server.key /alidata/server/httpd/conf/ssl/server.key cp demoCA/cacert.pem /alidata/server/httpd/conf/ssl/ca.crt cp -r ssl /alidata/server/httpd/conf/RB9HTML5中文学习网 - HTML5先行者学习网

  编辑/alidata/server/httpd/conf/extra/httpd-ssl.conf文件,找到SSLCertificateFile、SSLCertificateKeyFile、SSLCACertificatePath、SSLCACertificateFile进行修改:RB9HTML5中文学习网 - HTML5先行者学习网

  # 指定服务器证书位置RB9HTML5中文学习网 - HTML5先行者学习网

  SSLCertificateFile "/alidata/server/httpd/conf/ssl/server.crt"RB9HTML5中文学习网 - HTML5先行者学习网

  # 指定服务器证书key位置RB9HTML5中文学习网 - HTML5先行者学习网

  SSLCertificateKeyFile "/alidata/server/httpd/conf/ssl/server.key"RB9HTML5中文学习网 - HTML5先行者学习网

  # 证书目录RB9HTML5中文学习网 - HTML5先行者学习网

  SSLCACertificatePath "/alidata/server/httpd/conf/ssl"RB9HTML5中文学习网 - HTML5先行者学习网

  # 根证书位置RB9HTML5中文学习网 - HTML5先行者学习网

  SSLCACertificateFile "/alidata/server/httpd/conf/ssl/ca.crt"RB9HTML5中文学习网 - HTML5先行者学习网

  修改vhost配置vim /alidata/server/httpd/conf/vhosts/phpwind.confRB9HTML5中文学习网 - HTML5先行者学习网

  SSLCertificateFile /alidata/server/httpd/conf/ssl/server.crtRB9HTML5中文学习网 - HTML5先行者学习网

  SSLCertificateKeyFile /alidata/server/httpd/conf/ssl/server.keyRB9HTML5中文学习网 - HTML5先行者学习网

  SSLCACertificatePath /alidata/server/httpd/conf/sslRB9HTML5中文学习网 - HTML5先行者学习网

  SSLCACertificateFile /alidata/server/httpd/conf/ssl/ca.crtRB9HTML5中文学习网 - HTML5先行者学习网

  ServerName www.casetree.cnRB9HTML5中文学习网 - HTML5先行者学习网

  DocumentRoot /alidata/wwwRB9HTML5中文学习网 - HTML5先行者学习网

  最后,重启Apache服务器,在浏览器输入网址查看是否配置成功。我这里是个人使用,申请的是免费的证书,我申请证书的网站是沃通。RB9HTML5中文学习网 - HTML5先行者学习网

  搭建的成果:https://www.casetree.cnRB9HTML5中文学习网 - HTML5先行者学习网

  第二种、自建证书配置HTTPS服务器RB9HTML5中文学习网 - HTML5先行者学习网

  请查看我的上一篇自建证书配置HTTPS服务器RB9HTML5中文学习网 - HTML5先行者学习网

  三、使用nscurl对服务器进行检测RB9HTML5中文学习网 - HTML5先行者学习网

  搭建完HTTPS服务器之后,可以使用nscurl命令来进行检测,查看建立的HTTPS服务器是否能通过ATS特性。RB9HTML5中文学习网 - HTML5先行者学习网

  nscurl --ats-diagnostics --verbose https://casetree.cnRB9HTML5中文学习网 - HTML5先行者学习网

  如果HTTPS服务器能通过ATS特性,则上面所有测试案例都是PASS;如果某一项的Reuslt是FAIL,就找到ATS Dictionary来查看,就能知道HTTPS服务器不满足ATS哪个条件。 这里我前面碰到一个问题,就是自建证书的时候,通过此命令进行测试时,发现Result全是FAIL,而且在iOS的代码测试中也出现了一个很奇怪的现象,就是相同的代码,在iOS8.4请求数据完全正常,但是在iOS9上,直接是连接失败。最终发现,其实就是因为自建证书不受信任,是通不过ATS的,除非将NSAllowsArbitraryLoads设置为YES。RB9HTML5中文学习网 - HTML5先行者学习网

  四、iOS客户端RB9HTML5中文学习网 - HTML5先行者学习网

  在上面的第二大步骤当中,HTTPS服务器满足ATS默认的条件,而且SSL证书是通过权威的CA机构认证过的,那么我们在使用Xcode7开发的时候,对网络的适配什么都不用做,我们也能正常与服务器通信。但是,当我们对安全性有更高的要求时或者我们自建证书时,我们需要本地导入证书来进行验证。RB9HTML5中文学习网 - HTML5先行者学习网

  那么,如何本地导入证书进行验证呢?RB9HTML5中文学习网 - HTML5先行者学习网

  在这里先提一下,由于iOS客户端支持的证书是DER格式的,我们需要创建客户端证书。创建客户端证书,直接将服务端的CA根证书导出成DER格式就行。RB9HTML5中文学习网 - HTML5先行者学习网

  openssl x509 -inform PEM -outform DER -in ca.crt -out ca.cerRB9HTML5中文学习网 - HTML5先行者学习网

  导入完证书之后,我们分别来说说使用NSURLSession和AFNetworking来进行本地验证。RB9HTML5中文学习网 - HTML5先行者学习网

  首先,来说说使用NSURLSession验证RB9HTML5中文学习网 - HTML5先行者学习网

  验证步骤如下:RB9HTML5中文学习网 - HTML5先行者学习网

  导入CA根证书到工程中,即我们创建的ca.cerRB9HTML5中文学习网 - HTML5先行者学习网

  获取trust object,通过SecCertificateCreateWithData方法读取导入的证书的数据生成一个证书对象,然后通过SecTrustSetAnchorCertificates 设置这个证书为trust object的信任根证书(trusted anchor)RB9HTML5中文学习网 - HTML5先行者学习网

  通过SecTrustEvaluate方法去验证trust objectRB9HTML5中文学习网 - HTML5先行者学习网

  下面是主要OC实现代码,Demo工程我也放在github上了,有OC和Swift两种语言,下载Demo请点击HTTPSConnectDemo。RB9HTML5中文学习网 - HTML5先行者学习网

  - (void)viewDidLoad {RB9HTML5中文学习网 - HTML5先行者学习网

  [super viewDidLoad];RB9HTML5中文学习网 - HTML5先行者学习网

  //导入客户端证书RB9HTML5中文学习网 - HTML5先行者学习网

  NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"cer"];RB9HTML5中文学习网 - HTML5先行者学习网

  NSData *data = [NSData dataWithContentsOfFile:cerPath];RB9HTML5中文学习网 - HTML5先行者学习网

  SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) data);RB9HTML5中文学习网 - HTML5先行者学习网

  self.trustedCerArr = @[(__bridge_transfer id)certificate];RB9HTML5中文学习网 - HTML5先行者学习网

  //发送请求RB9HTML5中文学习网 - HTML5先行者学习网

  NSURL *testURL = [NSURL URLWithString:@"https://casetree.cn/web/test/demo.php"];RB9HTML5中文学习网 - HTML5先行者学习网

  NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];RB9HTML5中文学习网 - HTML5先行者学习网

  NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:testURL]];RB9HTML5中文学习网 - HTML5先行者学习网

  [task resume];RB9HTML5中文学习网 - HTML5先行者学习网

  // Do any additional setup after loading the view, typically from a nib.RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  #pragma mark - NSURLSessionDelegateRB9HTML5中文学习网 - HTML5先行者学习网

  - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challengeRB9HTML5中文学习网 - HTML5先行者学习网

  completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler{RB9HTML5中文学习网 - HTML5先行者学习网

  OSStatus err;RB9HTML5中文学习网 - HTML5先行者学习网

  NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;RB9HTML5中文学习网 - HTML5先行者学习网

  SecTrustResultType trustResult = kSecTrustResultInvalid;RB9HTML5中文学习网 - HTML5先行者学习网

  NSURLCredential *credential = nil;RB9HTML5中文学习网 - HTML5先行者学习网

  //获取服务器的trust objectRB9HTML5中文学习网 - HTML5先行者学习网

  SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;RB9HTML5中文学习网 - HTML5先行者学习网

  //将读取的证书设置为serverTrust的根证书RB9HTML5中文学习网 - HTML5先行者学习网

  err = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)self.trustedCerArr);RB9HTML5中文学习网 - HTML5先行者学习网

  if(err == noErr){RB9HTML5中文学习网 - HTML5先行者学习网

  //通过本地导入的证书来验证服务器的证书是否可信,如果将SecTrustSetAnchorCertificatesOnly设置为NO,则只要通过本地或者系统证书链任何一方认证就行RB9HTML5中文学习网 - HTML5先行者学习网

  err = SecTrustEvaluate(serverTrust, &trustResult);RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  if (err == errSecSuccess && (trustResult == kSecTrustResultProceed || trustResult == kSecTrustResultUnspecified)){RB9HTML5中文学习网 - HTML5先行者学习网

  //认证成功,则创建一个凭证返回给服务器RB9HTML5中文学习网 - HTML5先行者学习网

  disposition = NSURLSessionAuthChallengeUseCredential;RB9HTML5中文学习网 - HTML5先行者学习网

  credential = [NSURLCredential credentialForTrust:serverTrust];RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  else{RB9HTML5中文学习网 - HTML5先行者学习网

  disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  //回调凭证,传递给服务器RB9HTML5中文学习网 - HTML5先行者学习网

  if(completionHandler){RB9HTML5中文学习网 - HTML5先行者学习网

  completionHandler(disposition, credential);RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  注意:RB9HTML5中文学习网 - HTML5先行者学习网

  1、SecTrustSetAnchorCertificates方法会设置一个标示去屏蔽trust object对其它根证书的信任;如果你也想信任系统默认的根证书,请调用SecTrustSetAnchorCertificatesOnly方法,清空这个标示(设置为NO) 2、验证的方法不仅仅只有这一种,更多的验证方法,请参考HTTPS Server Trust EvaluationRB9HTML5中文学习网 - HTML5先行者学习网

  下面,来谈谈AFNetworking是如何验证的,我们如何使用AFNetworking。RB9HTML5中文学习网 - HTML5先行者学习网

  AFNetworking的证书验证工作是由AFSecurityPolicy来完成的,所以这里我们主要来了解一下AFSecurityPolicy。注意:我这里使用的是AFNetworking2.6.0,它跟2.5.0是有区别的。RB9HTML5中文学习网 - HTML5先行者学习网

  说到AFSecurityPolicy,我们必须要提到它三个重要的属性,如下:RB9HTML5中文学习网 - HTML5先行者学习网

  @property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode;RB9HTML5中文学习网 - HTML5先行者学习网

  @property (nonatomic, assign) BOOL allowInvalidCertificates;RB9HTML5中文学习网 - HTML5先行者学习网

  @property (nonatomic, assign) BOOL validatesDomainName;RB9HTML5中文学习网 - HTML5先行者学习网

  SSLPingMode是最重要的属性,它标明了AFSecurityPolicy是以何种方式来验证。它是一个枚举类型,这个枚举类型有三个值,分别是AFSSLPinningModeNone、AFSSLPinningModePublicKey、AFSSLPinningModeCertificate。其中,AFSSLPinningModeNone代表了AFSecurityPolicy不做更严格的验证,只要是系统信任的证书就可以通过验证,不过,它受到allowInvalidCertificates和validatesDomainName的影响;AFSSLPinningModePublicKey是通过比较证书当中公钥(PublicKey)部分来进行验证,通过SecTrustCopyPublicKey方法获取本地证书和服务器证书,然后进行比较,如果有一个相同,则通过验证,此方式主要适用于自建证书搭建的HTTPS服务器和需要较高安全要求的验证;AFSSLPinningModeCertificate则是直接将本地的证书设置为信任的根证书,然后来进行判断,并且比较本地证书的内容和服务器证书内容是否相同,来进行二次判断,此方式适用于较高安全要求的验证。RB9HTML5中文学习网 - HTML5先行者学习网

  allowInvalidCertificates属性代表是否允许不信任的证书通过验证,默认为NO。RB9HTML5中文学习网 - HTML5先行者学习网

  validatesDomainName属性代表是否验证主机名,默认为YES。RB9HTML5中文学习网 - HTML5先行者学习网

  接下来,我们说下验证流程。验证流程主要放在AFSecurityPolicy的- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain方法当中。 cRB9HTML5中文学习网 - HTML5先行者学习网

  - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrustRB9HTML5中文学习网 - HTML5先行者学习网

  forDomain:(NSString *)domainRB9HTML5中文学习网 - HTML5先行者学习网

  {RB9HTML5中文学习网 - HTML5先行者学习网

  //当使用自建证书验证域名时,需要使用AFSSLPinningModePublicKey或者AFSSLPinningModeCertificateRB9HTML5中文学习网 - HTML5先行者学习网

  if (domain && self.allowInvalidCertificates && self.validatesDomainName && (self.SSLPinningMode == AFSSLPinningModeNone || [self.pinnedCertificates count] == 0)) {RB9HTML5中文学习网 - HTML5先行者学习网

  NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning.");RB9HTML5中文学习网 - HTML5先行者学习网

  return NO;RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  NSMutableArray *policies = [NSMutableArray array];RB9HTML5中文学习网 - HTML5先行者学习网

  //需要验证域名时,需要添加一个验证域名的策略RB9HTML5中文学习网 - HTML5先行者学习网

  if (self.validatesDomainName) {RB9HTML5中文学习网 - HTML5先行者学习网

  [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)];RB9HTML5中文学习网 - HTML5先行者学习网

  } else {RB9HTML5中文学习网 - HTML5先行者学习网

  [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()];RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  //设置验证的策略,可以是多个RB9HTML5中文学习网 - HTML5先行者学习网

  SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);RB9HTML5中文学习网 - HTML5先行者学习网

  //SSLPinningMode为AFSSLPinningModeNone时,allowInvalidCertificates为YES,则代表服务器任何证书都能验证通过;如果它为NO,则需要判断此服务器证书是否是系统信任的证书RB9HTML5中文学习网 - HTML5先行者学习网

  if (self.SSLPinningMode == AFSSLPinningModeNone) {RB9HTML5中文学习网 - HTML5先行者学习网

  if (self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust)){RB9HTML5中文学习网 - HTML5先行者学习网

  return YES;RB9HTML5中文学习网 - HTML5先行者学习网

  } else {RB9HTML5中文学习网 - HTML5先行者学习网

  return NO;RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  } else if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) {RB9HTML5中文学习网 - HTML5先行者学习网

  return NO;RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  //获取服务器证书的内容RB9HTML5中文学习网 - HTML5先行者学习网

  NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);RB9HTML5中文学习网 - HTML5先行者学习网

  switch (self.SSLPinningMode) {RB9HTML5中文学习网 - HTML5先行者学习网

  case AFSSLPinningModeNone:RB9HTML5中文学习网 - HTML5先行者学习网

  default:RB9HTML5中文学习网 - HTML5先行者学习网

  return NO;RB9HTML5中文学习网 - HTML5先行者学习网

  case AFSSLPinningModeCertificate: {RB9HTML5中文学习网 - HTML5先行者学习网

  //AFSSLPinningModeCertificate是直接将本地的证书设置为信任的根证书,然后来进行判断,并且比较本地证书的内容和服务器证书内容是否相同,如果有一个相同则返回YESRB9HTML5中文学习网 - HTML5先行者学习网

  NSMutableArray *pinnedCertificates = [NSMutableArray array];RB9HTML5中文学习网 - HTML5先行者学习网

  for (NSData *certificateData in self.pinnedCertificates) {RB9HTML5中文学习网 - HTML5先行者学习网

  [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)];RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  //设置本地的证书为根证书RB9HTML5中文学习网 - HTML5先行者学习网

  SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates);RB9HTML5中文学习网 - HTML5先行者学习网

  //通过本地的证书来判断服务器证书是否可信,不可信,则验证不通过RB9HTML5中文学习网 - HTML5先行者学习网

  if (!AFServerTrustIsValid(serverTrust)) {RB9HTML5中文学习网 - HTML5先行者学习网

  return NO;RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  //判断本地证书和服务器证书的内容是否相同RB9HTML5中文学习网 - HTML5先行者学习网

  NSUInteger trustedCertificateCount = 0;RB9HTML5中文学习网 - HTML5先行者学习网

  for (NSData *trustChainCertificate in serverCertificates) {RB9HTML5中文学习网 - HTML5先行者学习网

  if ([self.pinnedCertificates containsObject:trustChainCertificate]) {RB9HTML5中文学习网 - HTML5先行者学习网

  trustedCertificateCount++;RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  return trustedCertificateCount > 0;RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  case AFSSLPinningModePublicKey: {RB9HTML5中文学习网 - HTML5先行者学习网

  //AFSSLPinningModePublicKey是通过比较证书当中公钥(PublicKey)部分来进行验证,通过SecTrustCopyPublicKey方法获取本地证书和服务器证书,然后进行比较,如果有一个相同,则通过验证RB9HTML5中文学习网 - HTML5先行者学习网

  NSUInteger trustedPublicKeyCount = 0;RB9HTML5中文学习网 - HTML5先行者学习网

  NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust);RB9HTML5中文学习网 - HTML5先行者学习网

  //判断服务器证书的公钥与本地的证书公钥是否相同,相同则客户端认证通过RB9HTML5中文学习网 - HTML5先行者学习网

  for (id trustChainPublicKey in publicKeys) {RB9HTML5中文学习网 - HTML5先行者学习网

  for (id pinnedPublicKey in self.pinnedPublicKeys) {RB9HTML5中文学习网 - HTML5先行者学习网

  if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) {RB9HTML5中文学习网 - HTML5先行者学习网

  trustedPublicKeyCount += 1;RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  return trustedPublicKeyCount > 0;RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  return NO;RB9HTML5中文学习网 - HTML5先行者学习网

  }RB9HTML5中文学习网 - HTML5先行者学习网

  说了验证流程,我们最后来看看AFNetworking怎么使用,代码如下:RB9HTML5中文学习网 - HTML5先行者学习网

  _httpClient = [[BGAFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];RB9HTML5中文学习网 - HTML5先行者学习网

  AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];RB9HTML5中文学习网 - HTML5先行者学习网

  //是否允许CA不信任的证书通过RB9HTML5中文学习网 - HTML5先行者学习网

  policy.allowInvalidCertificates = YES;RB9HTML5中文学习网 - HTML5先行者学习网

  //是否验证主机名RB9HTML5中文学习网 - HTML5先行者学习网

  policy.validatesDomainName = YES;RB9HTML5中文学习网 - HTML5先行者学习网

  _httpClient.securityPolicy = policy;RB9HTML5中文学习网 - HTML5先行者学习网

  这里我就没有建立Demo了,如果要看的话,可以看看我写的一个框架BGNetwork,里面的Demo对ATS进行了适配,AFNetworking的使用放在BGNetworkConnector类里面的- (instancetype)initWithBaseURL:(NSString *)baseURL delegate:(id)delegate初始化方法中。RB9HTML5中文学习网 - HTML5先行者学习网

  五、适配ATSRB9HTML5中文学习网 - HTML5先行者学习网

  前面的内容讲述都是满足ATS特性的情况,但若是服务器是自建证书搭建的,或者TLS版本是1.0的话,服务器又不能轻易改动,那么我们客户端如何适配呢? 不急,我们可以在工程中的Info.plist文件当中进行设置,主要参照下图:RB9HTML5中文学习网 - HTML5先行者学习网

适配iOS 9之ATS

  如果是自建证书,没有经过权威机构认证的证书,那么需要将NSAllowsArbitraryLoads设置为YES才能通过。NSAllowsArbitraryLoads为YES,以前的HTTP请求也能通过。RB9HTML5中文学习网 - HTML5先行者学习网

  如果是认证过的证书,那么可以通过nscurl --ats-diagnostics --verbose https://casetree.cn这样的命令来查看服务器支持的ATS Dictionary,然后进行对应的设置。RB9HTML5中文学习网 - HTML5先行者学习网

  适配的部分,也可以参照Demo1_iOS9网络适配_ATS:改用更安全的HTTPSRB9HTML5中文学习网 - HTML5先行者学习网

(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助