iOS AFNetworking框架HTTPS请求配置

iOS在Apple公司的强制要求下,数据传输必须按照ATS(App Transefer Security)条款。关于AFNetworking框架传输HTTPS数据。

一.AllowsArbitraryLoads 白名单机制

NSAllowsArbitraryLoads是ATS推广过程中的产物,当然也许可持续很久甚至永久,为了访问HTTP服务,一般需要绕过ATS限制,需要配置info.plist文件

<key>NSAppTransportSecurity</key> 
<dict> 
        <key>NSAllowsArbitraryLoads</key> 
        <true/> 
 </dict>  

这种机制实际上是允许了所有HTTP 和HTTPS的访问,显然,这种做法实际上很危险。设置为false就能避免绕开ATS,问题是我们真的需要完全关闭这个选项么?

比如某些文件服务器,CDN服务器配置HTTPS反而影响传输速度,这种情况下HTTP反而具有很高的优越性。因此,对于这类服务器的HTTP传输,我们其实也可以使用如下方式(设置白名单),白名单之外的必须使用HTTPS协议。

<key>NSAppTransportSecurity</key> 
    <dict> 
        <key>NSExceptionDomains</key> 
        <dict> 
            <key>lib.baidu.com</key> 
            <dict> 
                <key>NSIncludesSubdomains</key> 
                <true/> 
            </dict> 
            <key>oss.fastdfs.cn</key> 
            <dict> 
                <key>NSIncludesSubdomains</key> 
                <true/> 
            </dict> 
           </dict> 
   </dict>  

二.免证书验证

免证书验证,一般来说是client证书库不会把server传输来的证书进行校验。

举个例子

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
//允许非权威机构颁发的证书 
manager.securityPolicy.allowInvalidCertificates = YES; 
//也不验证域名一致性 
manager.securityPolicy.validatesDomainName = NO; 
//关闭缓存避免干扰测试 
manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData; 
 
[manager GET:@"https://www.baidu.com/s?wd=https" parameters:nil progress:nil  
success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) { 
        NSLog(@"%@",responseObject); 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
        NSLog(@"%@",error); 
}];  

这种方式导致我们的app容易遭到中间人攻击,原因并不完全是我们设置了allowInvalidCertificates=YES 和validatesDomainName=NO,而是本地证书库中没有添加server的CA证书,只要是任意的https都能伪造为服务器。

因此,我们并不推荐使用这种方式。

三.证书验证

3.1 加密标准分类

证书验证分为2类,一类是单向认证,一类是双认证。

此外,我们还需要区分证书与证书库的区别,证书库类型包括PKCS12,JKS,BKS等,其中,PKCS12是互联网标准,可以跨平台跨语言(支持Android,iOS,WP,PC,JAVA,PHP...),JKS是Java标准,只能在Java平台和Java语言下使用,BKS是 Bouncy Castle公司的加密标准,作为Android平台支持SSL/TLS加密套件PKCS12的补充,其加密强度很高,但是目前只用于Android平台。证书的定义是保存在证书库中的数字签名信息或者单独的证书文件,如crt,pem,cer等文件。在说加密之前,先来看看自签名证书。

3.2 自签名证书 vs 第三方权威机构证书

有人可能会有疑问,自签名证书和第三方权威机构的证书的效用是否一样?

实际上本人认为完全一样,在互联网中,基于B/S架构的服务中,B端通常导入了第三方权威机构的根证书(ROOT CA),实际上就是为了验证网站的CA证书是不是安全的,并且验证是不是由权威的安全机构签发的证书。问题是,我们的App与Server是C/S架构,每个app最多也就只能访问有限的几个网址,我们自己做的app实际上本身就是信任自己的所设置的站点URL的,也就是说我们自己人相信自己人。我们的证书只是为了数据安全传输,不被中间人攻击,因此完全没必要使用(ROOT CA),但是具体来说,到目前为止也没人试过这种方式是否可以通过审核。

我试图找第三方CA证书机构交流,貌似他只是说这是苹果的规定,实际上自签名证书本质上没什么问题,只要密钥长度,复杂度,加密方式等达到要求即可。

因此,苹果如果真的要求必须使用第三方CA ROOT签名的规则,本身是不合理的。这些问题也没法避免,不过,如果苹果允许自签名证书的话,设置allowInvalidCertificates=YES即可。

3.3 单向认证

需要准备的文件:服务端证书库 , 服务端导出的证书

单向认证,实际上说的是只有Client端对Server端的证书进行验证,Server不需要验证Client端的证书。

自定义类:MyAFNetworking

+ (AFHTTPSessionManager *)manager; 
{ 
    static AFHTTPSessionManager *shareInstance = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
 
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
        shareInstance = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:BaseHttpURLString] sessionConfiguration:configuration]; 
        //设置请求参数的类型:JSON 
        shareInstance.requestSerializer = [AFJSONRequestSerializer serializer]; 
        //设置服务器返回结果的类型:JSON (AFJSONResponseSerializer,AFHTTPResponseSerializer) 
        shareInstance.responseSerializer = [AFJSONResponseSerializer serializer]; 
        //设置请求的超时时间 
        shareInstance.requestSerializer.timeoutInterval = 20.0f; 
        //设置ContentType 
        shareInstance.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/json", @"text/plain", @"text/javascript", @"text/xml", @"image/jpeg",@"image/png", nil]; 
 
        // https配置 
        NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"你的证书名" ofType:@"cer"]; 
        NSData *certData = [NSData dataWithContentsOfFile:cerPath]; 
        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[[NSSet alloc] initWithObjects:certData, nil]]; 
 
        NSSet *dataSet = [[NSSet alloc] initWithObjects:certData, nil]; //这里可以添加多个server的证书 
 
        // setPinnedCertificates 设置证书文件(可能不止一个证书) 
        [securityPolicy setPinnedCertificates:dataSet]; 
        // allowInvalidCertificates 是否允许无效证书 
        [securityPolicy setAllowInvalidCertificates:NO]; 
        // validatesDomainName 是否需要验证域名 
        [securityPolicy setValidatesDomainName:YES]; 
 
        shareInstance.securityPolicy = securityPolicy; 
    }); 
    return shareInstance; 
} 

注意:以上说的证书是从服务器端到处的cer或者crt证书,这类证书是X509 Der格式的二进制编码证书,不是X509 PAM格式的Base64编码证书

3.4 双向认证

iOS和Android一样,客户端证书库类型可以是PKCS12类型的pfx证书,此类证书包含私钥,公钥和证书,并且由密码。

双向认证一般用于安全要求比较高的产品,比如金融类app,政府app等特殊行业。

需要准备的文件:服务端证书库,服务端证书信任库 , 服务端导出的证书,客户端证书库,客户端证书

注[1]:服务端证书库可以和服务端信任证书库使用同一个证书库,唯一要做的是把客户端证书导入进行。

注[2]:客户端证书一般使用跨平台的PKCS12证书库(pfx或p12),必须记住证书库密钥,此类证书库同时包含私钥,公钥和证书。

3.4.1 信任服务器

本步骤用来校验客户端证书,和单向认证完全相同

自定义类:MyAFNetworking

+ (AFHTTPSessionManager *)manager; 
{ 
    static AFHTTPSessionManager *shareInstance = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
 
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
        shareInstance = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:BaseHttpURLString] sessionConfiguration:configuration]; 
        //设置请求参数的类型:JSON 
        shareInstance.requestSerializer = [AFJSONRequestSerializer serializer]; 
        //设置服务器返回结果的类型:JSON (AFJSONResponseSerializer,AFHTTPResponseSerializer) 
        shareInstance.responseSerializer = [AFJSONResponseSerializer serializer]; 
        //设置请求的超时时间 
        shareInstance.requestSerializer.timeoutInterval = 20.0f; 
        //设置ContentType 
        shareInstance.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/json", @"text/plain", @"text/javascript", @"text/xml", @"image/jpeg",@"image/png", nil]; 
 
        // https配置 
        NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"你的证书名" ofType:@"cer"]; 
        NSData *certData = [NSData dataWithContentsOfFile:cerPath]; 
        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[[NSSet alloc] initWithObjects:certData, nil]]; 
 
        NSSet *dataSet = [[NSSet alloc] initWithObjects:certData, nil]; //这里可以添加多个server的证书 
 
        // setPinnedCertificates 设置证书文件(可能不止一个证书) 
        [securityPolicy setPinnedCertificates:dataSet]; 
        // allowInvalidCertificates 是否允许无效证书 
        [securityPolicy setAllowInvalidCertificates:NO]; 
        // validatesDomainName 是否需要验证域名 
        [securityPolicy setValidatesDomainName:YES]; 
 
        shareInstance.securityPolicy = securityPolicy; 
    }); 
    return shareInstance; 
} 

3.4.2 提供客户端证书和证书库

/* 
* 
** 
* 创建服务器信任客户端的认证条件 
** 
*/ 
+(AFHTTPSessionManager *) createCredentialsClient 
{ 
__block AFHTTPSessionManager * manager = [MyAFNetworking manager]; 
[manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession*session, NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing*_credential) { 
    NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; 
    __autoreleasing NSURLCredential *credential =nil; 
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { 
        if([manager.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { 
            credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; 
            if(credential) { 
                disposition =NSURLSessionAuthChallengeUseCredential; 
            } else { 
                disposition =NSURLSessionAuthChallengePerformDefaultHandling; 
            } 
        } else { 
            disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; 
        } 
    } else { 
        // client authentication 
        SecIdentityRef identity = NULL; 
        SecTrustRef trust = NULL; 
        NSString *p12 = [[NSBundle mainBundle] pathForResource:@"client"ofType:@"pfx"]; 
        NSFileManager *fileManager =[NSFileManager defaultManager]; 
 
        if(![fileManager fileExistsAtPath:p12]) 
        { 
            NSLog(@"client.p12:not exist"); 
        } 
        else 
        { 
            NSData *PKCS12Data = [NSData dataWithContentsOfFile:p12]; 
            #加载PKCS12证书,pfx或p12 
            if ([MyAFNetworking extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data]) 
            { 
                SecCertificateRef certificate = NULL; 
                SecIdentityCopyCertificate(identity, &certificate); 
                const void*certs[] = {certificate}; 
                CFArrayRef certArray =CFArrayCreate(kCFAllocatorDefault, certs,1,NULL); 
                credential =[NSURLCredential credentialWithIdentity:identity certificates:(__bridge  NSArray*)certArray persistence:NSURLCredentialPersistencePermanent]; 
                disposition =NSURLSessionAuthChallengeUseCredential; 
            } 
        } 
    } 
    *_credential = credential; 
    return disposition; 
}]; 
 
return manager; 
} 
 
/** 
**加载PKCS12证书,pfx或p12 
**  
**/ 
+(BOOL)extractIdentity:(SecIdentityRef*)outIdentity andTrust:(SecTrustRef *)outTrust fromPKCS12Data:(NSData *)inPKCS12Data { 
    OSStatus securityError = errSecSuccess; 
    //client certificate password 
    NSDictionary*optionsDictionary = [NSDictionary dictionaryWithObject:@"你的p12密码" 
                                                                forKey:(__bridge id)kSecImportExportPassphrase]; 
 
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); 
    securityError = SecPKCS12Import((__bridge CFDataRef)inPKCS12Data,(__bridge CFDictionaryRef)optionsDictionary,&items); 
 
    if(securityError == 0) { 
        CFDictionaryRef myIdentityAndTrust =CFArrayGetValueAtIndex(items,0); 
        const void*tempIdentity =NULL; 
        tempIdentity= CFDictionaryGetValue (myIdentityAndTrust,kSecImportItemIdentity); 
        *outIdentity = (SecIdentityRef)tempIdentity; 
        const void*tempTrust =NULL; 
        tempTrust = CFDictionaryGetValue(myIdentityAndTrust,kSecImportItemTrust); 
        *outTrust = (SecTrustRef)tempTrust; 
    } else { 
        NSLog(@"Failedwith error code %d",(int)securityError); 
        return NO; 
    } 
    return YES; 
} 

通过以上方式,我们便能实现双向认证了

AFHTTPSessionManager * manager = [MyAFNetworking createCredentialsClient];  

来自:http://mobile.51cto.com/iphone-537758.htm

最后的话:FOR Freedom 、最后,安利一些去油+管的稳定好用的+速器代理。

祝大家在YouTube上想消磨时间的逛个痛快,想锻炼英语获取知识的学有所成

加速器推荐 免费方案 付费方案 官方网站
一枝红杏加速器 免费方案暂无,稳定高速 输入8折优惠码wh80,年付只需80元/年 官网直达
安云加速器 最好用的外贸VPN 最低¥30/月 官网直达
LoCo加速器 每天免费2小时 最低¥15/月 官网直达

稳定好用的+速器代理: http://whosmall.com/go/yzhx

本文标签: YouTube 看youtube视频 学习外语上youtube YouTube1080p 上YouTube

转自 SUN‘S BLOG - 专注互联网知识,分享互联网精神!

原文地址 你知道YouTube到底有多强大吗?如何上YouTube及最强攻略

相关阅读Chrome 扩展 Stylish :给不喜欢某个网站一键「换肤」

相关阅读将 QQ 音乐、网易云音乐和虾米音乐资源「整合」一起的Chrome 扩展Listen 1

相关阅读8 个「新标签页」Chrome 扩展: 教你把 New Tab 页面玩的溜溜溜

相关阅读7 款实用 Chrome 扩展推荐:帮你提升 Chrome 使用体验

相关阅读无扩展就不是 Chrome 了:15 款优质的Chrome 扩展推荐给大家

相关阅读12 款不能少的使网页浏览获得的最佳体验Chrome 扩展

相关阅读5 款可以带来幸福感的 Chrome 扩展

相关阅读: 关于 Android 中的 Palette 类的使用案例:色彩自适应的 Toolbar

相关阅读:GIT能做什么、它和SVN在深层次上究竟有什么不同

相关阅读:分享一些对开发者最有用的、用户友好和功能丰富的Google Chrome扩展工具

相关阅读:分享一些实际Android开发过程中很多相见恨晚的工具或网站

相关阅读:我是 G 粉,一直关注 Google,最近 Google 有一些小动作,可能很多人不太了解

相关阅读:机器学习引领认知领域的技术创新,那么SaaS行业会被机器学习如何改变?

相关阅读:VPS 教程系列:Dnsmasq + DNSCrypt + SNI Proxy 顺畅访问 Google 配置教程

相关阅读: 最有用:2017最新能上Google、Facebook的方法

相关BLOG:SUN’S BLOG - 专注互联网知识,分享互联网精神!去看看:www.whosmall.com

时间: 2024-11-06 02:55:07

iOS AFNetworking框架HTTPS请求配置的相关文章

iOS开发 支持https请求以及ssl证书配置(转)

原文地址:http://blog.5ibc.net/p/100221.html 众所周知,苹果有言,从2017年开始,将屏蔽http的资源,强推https 楼主正好近日将http转为https,给还没动手的朋友分享一二 一.证书准备 1.证书转换 在服务器人员,给你发送的crt证书后,进到证书路径,执行下面语句 // openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der 这样你就可以得到cer类型的证书了.双击,导入电脑. 2.证书放入工程 1

教你写Android网络框架之请求配置与Response缓存

前言 在教你写Android网络框架的前三篇文章中,我们从基本结构到代码实现,剖析了一个简单的网络框架应该是怎样运作的,以及在面对各式各样的需求时应该如何对代码做出处理,在深入了解网络框架的同时学习到一些简单的面向对象设计原则.正如第一篇博文所说,SimpleNet框架参照的是Volley实现,甚至有一些类名也是一样的.我们的目标并不是要重新发明轮子,而是以学习轮子制作的过程来达到提升自我的目的.SimpleNet只是一个简单的网络框架实现,没有经过严格的测试以及市场检验,不建议大家在项目中使用

十分钟学会Charles抓包(iOS的http/https请求)

Charles安装 HTTP抓包 HTTPS抓包 1. Charles安装 官网下载安装Charles:https://www.charlesproxy.com/download/ 2. HTTP抓包 (1)查看电脑IP地址 (2)设置手机HTTP代理 手机连上电脑,点击"设置->无线局域网->连接的WiFi",设置HTTP代理:服务器为电脑IP地址:如192.168.1.169端口:8888 设置代理后,需要在电脑上打开Charles才能上网 (3)电脑上打开Charle

Fiddler抓取HTTPS请求配置

由于fiddler安装后默认只能抓取http请求,如果需要抓取https请求需要进行配置.配置方式:Tools--->Options--->HTTPS,勾选CaptureHTTPS CONNECTs.Decrypt HTTPS traffic .ignore server certificate errors(unsafe),点击OK,会弹出证书直接确认即可. 此时,在电脑chrome浏览器上就可以访问https的请求了,且fiddler会话列表上就可以显示出https请求.在配置移动端证书之

Charles抓包(iOS的http/https请求)

1. Charles安装 官网下载安装Charles:https://www.charlesproxy.com/download/ 2. HTTP抓包 (1)查看电脑IP地址 (2)设置手机HTTP代理 手机连上电脑,点击"设置->无线局域网->连接的WiFi",设置HTTP代理:服务器为电脑IP地址:如192.168.1.169端口:8888 3. HTTPS抓包 HTTPS的抓包需要在HTTP抓包基础上再进行设置 (1)安装SSL证书到手机设备 点击 Help ->

[iOS AFNetworking框架实现HTTP请求、多文件图片上传下载]

简单的JSON的HTTP传输就不说了,看一个简单的DEMO吧. 主要明白parameters是所填参数,类型是字典型.我把这部分代码封装起来了,以便多次调用.也许写在一起更清楚点. #pragma mark - JSON方式post提交数据 - (void)postJSONWithUrl:(NSString *)urlStr parameters:(id)parameters success:(void (^)(id responseObject))success fail:(void (^)(

iOS使用自签名证书实现HTTPS请求

由于苹果规定2017年1月1日以后,所有APP都要使用HTTPS进行网络请求,否则无法上架,因此研究了一下在iOS中使用HTTPS请求的实现.相信大家对HTTPS都或多或少有些了解,这里我就不再介绍了,主要功能就是将传输的报文进行加密,提高安全性. 1.证书准备 证书分为两种,一种是花钱向认证的机构购买的证书,服务端如果使用的是这类证书的话,那一般客户端不需要做什么,用HTTPS进行请求就行了,苹果内置了那些受信任的根证书的.另一种是自己制作的证书,使用这类证书的话是不受信任的(当然也不用花钱买

Fiddler抓取https请求 &amp; Fiddler抓包工具常用功能详解

大家好,我是TT,互联网测试行业多年,没有牛逼的背景,也没有什么可炫耀的,唯独比他人更努力,在职场打拼.遇到过的坑,走过的弯路,愿意与大家分享,分享自己的经验,少走弯路.首发于个人公众号[测试架构师] 原文如下: 先来看一个小故事: 小T在测试APP时,打开某个页面展示异常,于是就跑到客户端开发小A那里说:"你这个页面做的有问题,页面展示异常":小A说:"这哪是我的问题,你去找后台吧,后台接口返回数据有问题":小T就屁颠屁颠的跑到后台接口开发小M那里说:"

iOS网络层框架之AFNetworking与 ASIHTTPRequest对比

在开发iOS应用过程中,如何高效的与服务端API进行数据交换,是一个常见问题.一般开发者都会选择一个第三方的网络组件作为服务,以提高开发效率和稳定性.这些组件把复杂的网络底层操作封装成友好的类和方法,并且加入异常处理等. 那么,大家最常用的组件是什么?这些组件是如何提升开发效率和稳定性的?哪一款组件适合自己,是 AFNetworking(AFN)还是 ASIHTTPRequest(ASI)?几乎每一个iOS互联网应用开发者都会面对这样的选择题,要从这两个最常用的组件里选出一个好的还真不是那么容易