iOS适配https详解
马上就要元旦了,网上流传元旦之后苹果会对所有的app进行https的验证,据说会拒绝所有没有使用https的app。但是后来又听说是我们开发者误解了,元旦过后还是会支持http,不过开发者需要说明为什么不用https。不过躲得过初一躲不过十五,还是早点适配https好些啊。然后弄了几天找了好多博客和文档,才暂时解决了这个问题。所谓https,只不过是在http的基础上增加了ssl层的验证(这样说不是很准确),也就是在原来的数据包的基础上加密了一下,然而加密的工作不需要我们开发者来做,只需在对的位置做好证书的验证就行了。其实我对ssl层理解也不深,想着以后有时间一定要把网络这一块掌握,不然下次碰到这种问题还是不好解决。废话不多说,还是先看看代码吧。
首先是对NSURLConnection的适配,不管是原生的还是AF的,归根结底都是要用它去连接服务器。
1.如果使用AF进行网络数据请求,那么使用如下方法即可:
- (AFSecurityPolicy*)customSecurityPolicy
{
//先导入证书
//在这加证书,一般情况适用于单项认证
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ailian" ofType:@"cer"];//证书的路径
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
if (certData==nil) {
return nil;
}
// AFSSLPinningModeCertificate 使用证书验证模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
// allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
// 如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates = YES;
//validatesDomainName 是否需要验证域名,默认为YES;
//假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
//置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
//如置为NO,建议自己添加对应域名的校验逻辑。
securityPolicy.validatesDomainName = NO;
securityPolicy.pinnedCertificates = @[certData];
return securityPolicy;
}
其实,在这里不需要使用服务器的证书,本人亲测过。不过为了保险起见还是加上,还需要注意一点,AF3.0需要用到der格式的证书。
然后加上下面的代码:
_manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:[self getHostURL]]];
[_manager setSecurityPolicy:[self customSecurityPolicy]];
2.如果是原生的NSURLConnection,那么需要在NSURLConnectionDelegate的一个方法里面加代码,如下:
- (void)connection:(NSURLConnection *)connection
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSString *thePath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"];
//导入证书 NSLog(@"thePath===========%@",thePath);
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data; SecIdentityRef identity = NULL;
// extract the ideneity from the certificate
[self extractP12Data:inPKCS12Data toIdentity:&identity]; SecCertificateRef certificate = NULL;
SecIdentityCopyCertificate (identity, &certificate); const void *certs[] = {certificate};
// CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);
// create a credential from the certificate and ideneity, then reply to the challenge with the credential
//NSLog(@"identity=========%@",identity);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:nil persistence:NSURLCredentialPersistencePermanent]; // credential = [NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)certArray persistence:NSURLCredentialPersistencePermanent]; [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
}
接下来是对NSURLSession的适配,现在公认更好的网络请求类,支持后台的数据下载和上传,而且自身是安全的。然而,在使用NSURLSession时需要在一个代理方法里配置ssl证书。如下:
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
NSString *method = challenge.protectionSpace.authenticationMethod;
if([method isEqualToString:NSURLAuthenticationMethodServerTrust]){
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
return;
}
NSString *thePath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"];
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
CFDataRef inPKCS12Data = (CFDataRef)CFBridgingRetain(PKCS12Data);
SecIdentityRef identity;
// 读取p12证书中的内容
OSStatus result = [self extractP12Data:inPKCS12Data toIdentity:&identity];
if(result != errSecSuccess){
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
return;
}
SecCertificateRef certificate = NULL;
SecIdentityCopyCertificate (identity, &certificate);
const void *certs[] = {certificate};
CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, , NULL);
NSURLCredential *credential1 = [NSURLCredential credentialWithIdentity:identity certificates:(NSArray*)CFBridgingRelease(certArray) persistence:NSURLCredentialPersistencePermanent];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential1);
}
- (OSStatus) extractP12Data:(CFDataRef)inP12Data toIdentity:(SecIdentityRef*)identity {
OSStatus securityError = errSecSuccess;
CFStringRef password = CFSTR("clientepass");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, , NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, , , NULL);
securityError = SecPKCS12Import(inP12Data, options, &items);
if (securityError == ) {
CFDictionaryRef ident = (CFDictionaryRef)CFArrayGetValueAtIndex(items,);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(ident, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
}
if (options) {
CFRelease(options);
}
return securityError;
}
其实适配https没有我们想象的那么复杂,你找对了地方可能几分钟就弄好了,找不到,可能花几天。不管怎样,最后适配成功还是要感谢网上的一些大神,虽然官网上面也有答案,但毕竟时间不等人,等我研究透彻,估计苹果又会有新的东西出来吧。至此,希望能帮到正在为https适配而忧伤的小伙伴们。
iOS适配https详解的更多相关文章
- 了解iOS消息推送一文就够:史上最全iOS Push技术详解
本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表. 1.引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ.微信等IM界面处于前台时,聊天消息和指 ...
- iOS开发者证书-详解
iOS开发者证书-详解/生成/使用 本文假设你已经有一些基本的Xcode开发经验, 并注册了iOS开发者账号. 相关基础 加密算法 现代密码学中, 主要有两种加密算法: 对称密钥加密 和 公开密钥加密 ...
- 基于rem的移动端响应式适配方案(详解) 移动端H5页面的设计稿尺寸大小规范
基于rem的移动端响应式适配方案(详解) : https://www.jb51.net/article/118067.htm 移动端H5页面的设计稿尺寸大小规范 http://www.tuyiyi.c ...
- 公钥与私钥,HTTPS详解
1.公钥与私钥原理1)鲍勃有两把钥匙,一把是公钥,另一把是私钥2)鲍勃把公钥送给他的朋友们----帕蒂.道格.苏珊----每人一把.3)苏珊要给鲍勃写一封保密的信.她写完后用鲍勃的公钥加密,就可以达到 ...
- 转载]IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本 )
原文地址:IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本作者:佐佐木小次郎 因为最近项目上要用有关LBS的功能.于是我便做一下预研. 一般说来LBS功能一般分为两块:一块是地理 ...
- iOS中-Qutarz2D详解及使用
在iOS中Qutarz2D 详解及使用 (一)初识 介绍 Quartz 2D是二维绘图引擎. 能完成的工作有: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成 ...
- iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)
前言:一个路径可以包含由一个或者多个shape以及子路径subpath,quartz提供了很多方便的shape可以直接调用.例如:point,line,Arc(圆弧),Curves(曲线),Ellip ...
- iOS开发——Block详解
iOS开发--Block详解 1. Block是什么 代码块 匿名函数 闭包--能够读取其他函数内部变量的函数 函数变量 实现基于指针和函数指针 实现回调的机制 Block是一个非常有特色的语法,它可 ...
- iOS开发:详解Objective-C runTime
Objective-C总Runtime的那点事儿(一)消息机制 最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎 ...
随机推荐
- System.UnauthorizedAccessException Access to the path "/etc/mono/registry" is denied.
sudo mkdir /etc/mono/registry sudo mkdir /etc/mono/registry/LocalMachine sudo chmod g+rwx /etc/mono/ ...
- Hdu 5489 合肥网络赛 1009 Removed Interval
跳跃式LIS(nlogn),在普通的转移基础上增加一种可以跨越一段距离的转移,用一颗新的树状数组维护,同时,我们还要维护跨越完一次后面的转移,所以我用了3颗树状数组.. 比赛的时候一句话位置写错了,然 ...
- Linux的fasync驱动异步通知详解【转】
本文转载自:http://blog.csdn.net/coding__madman/article/details/51851338 版权声明:本文为博主原创文章,未经博主允许不得转载. 工作项目用有 ...
- phpcms v9调用自定义字段的方法步骤
代码如下:{loop $shigongtu $r}<img src="{$r[url]} " title="测试"/>{/loop} 2 首页,分页 ...
- HDU 2732:Leapin' Lizards(最大流)
http://acm.hdu.edu.cn/showproblem.php?pid=2732 题意:给出两个地图,蜥蜴从一个柱子跳跃到另外一个地方,那么这个柱子就可能会坍塌,第一个地图是柱子可以容忍跳 ...
- MVC系列2-Model
上一篇我讲了ASP.MET MVC的基础概念,我相信从上一篇,我们可以知道MVC的执行过程.这一篇我们开始讲解Model.我们知道,在我们的应用程序中,大多时候是在遵循业务逻辑通过UI操作数据.所以这 ...
- [已解决] java 增加 ALPN支持
添加javaVM参数: -Xbootclasspath/p:lib/alpn-boot-8.1.10.v20161026.jar 文章来源:http://www.cnblogs.com/gifisan ...
- weboffice控件使用不能嵌入网页
var s = ""s += "<object id=WebOffice1 height=586 width='100%' style='LEFT: 0px; TO ...
- Excel 数据关联
=INDEX(Sheet2!$A$2:$A$77,MATCH(A4,Sheet2!$C$2:$C$77,0))
- laravel框架总结(十) -- 返回值
以前用CI框架对于返回值没有过多关注,但是发现使用laravel框架的时候出现了一些小问题,特意实践总结了一些常用情形,希望对大家有所帮助 先理解几个概念: 1>StdClass 对象=&g ...