原文地址:http://blog.5ibc.net/p/101504.html

首先,需要明确你使用HTTP/HTTPS的用途,因为OSX和iOS平台提供了多种API,来支持不同的用途,官方文档《Making HTTP and HTTPS Requests》有详细的说明,而文档《HTTPS Server Trust Evaluation》则详细讲解了HTTPS验证相关知识,这里就不多说了。本文主要讲解我们最常用的NSURLConnection支持HTTPS的实现(NSURLSession的实现方法类似,只是要求授权证明的回调不一样而已),以及怎么样使用AFNetworking这个非常流行的第三方库来支持HTTPS。本文假设你对HTTP以及NSURLConnection的接口有了足够的了解。

1. 验证证书的API

相关的Api在Security Framework中,验证流程如下:

1). 第一步,先获取需要验证的信任对象(Trust Object)。这个Trust Object在不同的应用场景下获取的方式都不一样,对于NSURLConnection来说,是从delegate方法-connection:willSendRequestForAuthenticationChallenge:回调回来的参数challenge中获取([challenge.protectionSpace serverTrust])。

2). 使用系统默认验证方式验证Trust Object。SecTrustEvaluate会根据Trust Object的验证策略,一级一级往上,验证证书链上每一级数字签名的有效性(上一部分有讲解),从而评估证书的有效性。

3). 如第二步验证通过了,一般的安全要求下,就可以直接验证通过,进入到下一步:使用Trust Object生成一份凭证([NSURLCredential credentialForTrust:serverTrust]),传入challenge的sender中([challenge.sender useCredential:cred forAuthenticationChallenge:challenge])处理,建立连接。

4). 假如有更强的安全要求,可以继续对Trust Object进行更严格的验证。常用的方式是在本地导入证书,验证Trust Object与导入的证书是否匹配。更多的方法可以查看Enforcing Stricter Server Trust Evaluation,这一部分在讲解AFNetworking源码中会讲解到。

5). 假如验证失败,取消此次Challenge-Response Authentication验证流程,拒绝连接请求。

ps: 假如是自建证书的,则会跳过第二步,使用第三部进行验证,因为自建证书的根CA的数字签名未在操作系统的信任列表中。

iOS授权验证的API和流程大概了解了,下面,我们看看在NSURLConnection中的代码实现:

使用NSURLConnection支持HTTPS的实现

  1. // Now start the connection
  2. NSURL * httpsURL = [NSURL URLWithString:@"https://www.google.com"];
  3. self.connection = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:httpsURL] delegate:self];
  4. //回调
  5. - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
  6. //1)获取trust object
  7. SecTrustRef trust = challenge.protectionSpace.serverTrust;
  8. SecTrustResultType result;
  9. //2)SecTrustEvaluate对trust进行验证
  10. OSStatus status = SecTrustEvaluate(trust, &result);
  11. if (status == errSecSuccess &&
  12. (result == kSecTrustResultProceed ||
  13. result == kSecTrustResultUnspecified)) {
  14. //3)验证成功,生成NSURLCredential凭证cred,告知challenge的sender使用这个凭证来继续连接
  15. NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
  16. [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
  17. } else {
  18. //5)验证失败,取消这次验证流程
  19. [challenge.sender cancelAuthenticationChallenge:challenge];
  20. }
  21. }

上面是代码是通过系统默认验证流程来验证证书的。假如我们是自建证书的呢?这样Trust Object里面服务器的证书因为不是可信任的CA签发的,所以直接使用SecTrustEvaluate进行验证是不会成功。又或者,即使服务器返回的证书是信任CA签发的,又如何确定这证书就是我们想要的特定证书?这就需要先在本地导入证书,设置成需要验证的Anchor Certificate(就是根证书),再调用SecTrustEvaluate来验证。代码如下

  1. //先导入证书
  2. NSString * cerPath = ...; //证书的路径
  3. NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
  4. SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(cerData));
  5. self.trustedCertificates = @[CFBridgingRelease(certificate)];
  6. //回调
  7. - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
  8. //1)获取trust object
  9. SecTrustRef trust = challenge.protectionSpace.serverTrust;
  10. SecTrustResultType result;
  11. //注意:这里将之前导入的证书设置成下面验证的Trust Object的anchor certificate
  12. SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)self.trustedCertificates);
  13. //2)SecTrustEvaluate会查找前面SecTrustSetAnchorCertificates设置的证书或者系统默认提供的证书,对trust进行验证
  14. OSStatus status = SecTrustEvaluate(trust, &result);
  15. if (status == errSecSuccess &&
  16. (result == kSecTrustResultProceed ||
  17. result == kSecTrustResultUnspecified)) {
  18. //3)验证成功,生成NSURLCredential凭证cred,告知challenge的sender使用这个凭证来继续连接
  19. NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
  20. [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
  21. } else {
  22. //5)验证失败,取消这次验证流程
  23. [challenge.sender cancelAuthenticationChallenge:challenge];
  24. }
  25. }

建议采用本地导入证书的方式验证证书,来保证足够的安全性。更多的验证方法,请查看官方文档《HTTPS Server Trust Evaluation》

2. 使用AFNetworking来支持HTTPS

AFNetworking是iOS/OSX开发最流行的第三方开源库之一,其作者是非常著名的iOS/OSX开发者Mattt Thompson,其博客NSHipster也是iOS/OSX开发者学习和开阔技术视野的好地方。AFNetworking已经将上面的逻辑代码封装好,甚至更完善,在AFSecurityPolicy文件中,有兴趣可以阅读这个模块的代码;

AFNetworking上配置对HTTPS的支持非常简单:

  1. NSURL * url = [NSURL URLWithString:@"https://www.google.com"];
  2. AFHTTPRequestOperationManager * requestOperationManager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url];
  3. dispatch_queue_t requestQueue = dispatch_create_serial_queue_for_name("kRequestCompletionQueue");
  4. requestOperationManager.completionQueue = requestQueue;
  5. AFSecurityPolicy * securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
  6. //allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
  7. //如果是需要验证自建证书,需要设置为YES
  8. securityPolicy.allowInvalidCertificates = YES;
  9. //validatesDomainName 是否需要验证域名,默认为YES;
  10. //假如证书的域名与你请求的域名不一致,需把该项设置为NO
  11. //主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
  12. securityPolicy.validatesDomainName = NO;
  13. //validatesCertificateChain 是否验证整个证书链,默认为YES
  14. //设置为YES,会将服务器返回的Trust Object上的证书链与本地导入的证书进行对比,这就意味着,假如你的证书链是这样的:
  15. //GeoTrust Global CA
  16. // Google Internet Authority G2
  17. // *.google.com
  18. //那么,除了导入*.google.com之外,还需要导入证书链上所有的CA证书(GeoTrust Global CA, Google Internet Authority G2);
  19. //如是自建证书的时候,可以设置为YES,增强安全性;假如是信任的CA所签发的证书,则建议关闭该验证;
  20. securityPolicy.validatesCertificateChain = NO;
  21. requestOperationManager.securityPolicy = securityPolicy;

这就是AFNetworking的支持HTTPS的主要配置说明,AFHTTPSessionManager与之基本一致,就不重复了。

3. 总结

从2017年1月起,iOS必须支持HTTPS,所以HTTPS已经是大势所趋了。

如何在iOS上实现对HTTPS的支持(转)的更多相关文章

  1. fir.im Weekly - 如何在 iOS 上构建 TensorFlow 应用

    本期 fir.im Weekly 收集了最近新鲜出炉的 iOS /Android 技术分享,包括 iOS 系统开发 TensorFlow 教程.iOS 新架构.iOS Notifications 推送 ...

  2. ios中实现对UItextField,UITextView等输入框的字数限制

    本文转载至 http://blog.sina.com.cn/s/blog_9bf272cf01013lsd.html 2011-10-05 16:48 533人阅读 评论(0) 收藏 举报 1.    ...

  3. qml实现对SSL的支持(使用msys2,同时支持32和64位)超详细 good

    首先准备环境.两种方法,使用mingw64 或者VS 直接放上下载地址https://sourceforge.net/projects/msys2/我下载的是msys2-x86_64-20161025 ...

  4. 如何在IOS上调试Hybrid应用

    最近在找关于在xcode上调试Hybrid应用的方法,比如我想进行断点调试.日志打印.屏幕适配等等,刻意去搜了下方法,虽然之前已经大致知道了,这里系统归纳一下,原文在https://developer ...

  5. Mac上实现对Python的版本切换

    最近朋友邀请我帮忙写个比特币自动化交易程序,要求的平台是Okex,用Python写,之前到是自己学过一点自动化交易,不过是MT5的.看了一下Okex提供的API接口,和MT5不一样,它并没有现成的ID ...

  6. Netty实现对Websocket的支持

    一.WebSocket的简介及优势 WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准.WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的 ...

  7. 使用ASP.NET Web API自带的类库实现对CORS的支持(在开发中使用这种方式)(转载)

    在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中我们通过自定义的HttpMessageHandler为ASP.NET Web API赋予了跨域资源共享的能力,具体来 ...

  8. 打造安全的App!iOS安全系列之 HTTPS

    如何打造一个安全的App?这是每一个移动开发者必须面对的问题.在移动App开发领域,开发工程师对于安全方面的考虑普遍比较欠缺,而由于iOS平台的封闭性,遭遇到的安全问题相比于Android来说要少得多 ...

  9. iOS安全系列之 HTTPS

    作者:Jaminzzhang 如何打造一个安全的App?这是每一个移动开发者必须面对的问题.在移动App开发领域,开发工程师对于安全方面的考虑普遍比较欠缺,而由于iOS平台的封闭性,遭遇到的安全问题相 ...

随机推荐

  1. docker基本元素和底层实现

    docker是轻量级的操作系统虚拟化解决方案 优点 1.基于操作系统层面 2.启动速度快(秒级) 3.资源利用率高 4.性能高.易管理 docker有3大基本要素 分别是 1.镜像:只读模板,用来创建 ...

  2. mssql Sqlver 修改标识列方法

    摘自: http://www.cnblogs.com/badboy2008/articles/1145465.html MSSQL Server修改标识列方法   ----允许对系统表进行更新exec ...

  3. Thinkphp学习笔记-删除缓存

    Thinkphp的缓存数据在Cach文件夹下的Home文件夹下的文临时文件 清除方法:将缓存文件删除就可以了

  4. [Grunt] Watch && grunt-contrib-watch

    Watch is an essential component of any Grunt build, and you will find yourself using it in almost ev ...

  5. systemctl使用

    systemctl start httpd.service 这会启动httpd服务,就我们而言,Apache HTTP服务器. 要停掉它,需要以root身份使用该命令: systemctl stop ...

  6. 【Caffe代码解析】Layer网络层

    Layer 功能: 是全部的网络层的基类,当中.定义了一些通用的接口,比方前馈.反馈.reshape,setup等. #ifndef CAFFE_LAYER_H_ #define CAFFE_LAYE ...

  7. linux中的硬链接和软链接是什么

    Linux 文件系统最重要的特点之一是它的文件链接.链接是对文件的引用,这样您可以让文件在文件系统中多处被看到.不过,在 Linux 中,链接可以如同原始文件一样来对待.链接可以与普通的文件一样被执行 ...

  8. Android 使用ORMLite 操作数据库

    参考:http://blog.csdn.net/cjjky/article/details/7096987 ormlite 方法查询:http://ormlite.com/javadoc/ormlit ...

  9. 用pdb调试OpenStack Havana

    作为个人学习笔记分享,有任何问题欢迎交流! Note:若是想要用pdb调试OpenStack,必须通过Devstack安装它. Devstack安装Havana过程 1.   使用一般用户(非root ...

  10. TP5安装失败怎么办?

    安装TP5遇到这样的错误 TP5安装失败怎么办? [Mon Mar 13 06:24:58.011228 2017] [:error] [pid 10243] [client 192.168.28.1 ...