美文网首页学学人家的框架iOS开发网络相关
iOS 迁移到HTTPS(自建证书+单向验证+AF3.0+WKW

iOS 迁移到HTTPS(自建证书+单向验证+AF3.0+WKW

作者: vincent涵 | 来源:发表于2016-11-30 15:57 被阅读4650次

马上就2017年了,据说元旦apple就强制HTTPS了,就像之前强制IPV6一样任性,好方~~~
不到万不得已,项目经理不舍得买CA证书,于是就开始了坑爹的自建证书HTTPS之旅。

写在前面的提醒

① 还没到2017,苹果还没确切的说明对HTTPS的要求,所以目前还不确定自建证书到底可不可以通过审核。
② 网上很多人说自建证书必须禁掉ATS才能正常访问(App Transport Security Settings -> Allow Arbitrary Loads -> YES),但是在我的项目中没有禁掉ATS自建证书是可以正常使用的,欢迎大家讨论原因。

一、配置证书

1、服务器端那边配置https有一堆证书,试了好久才确定是哪个。
正常说应该是服务器那边最开始的root/ca证书,我们最终需要的格式是.der格式(AF3.0以上)或者.cer格式(AF3.0以下),给过来的格式根据情况不一定,如果是我们需要的格式最好,不是的话大家自行或者让服务端帮转。
我这边情况是给过来后缀名为.crt,拿到手后要转成.der格式或者.cer格式。

2、.crt转.der方法(终端):
openssl x509 -in /Users/mac/Desktop/ca.crt -out /Users/mac/Desktop/ca.der -outform DER
.crt转.cer方法(终端):
openssl x509 -in /Users/mac/Desktop/ca.crt -out /Users/mac/Desktop/ca.cer -outform DER

3、如果证书用错了,iOS这边会报“-999,已取消”的错误,(网上很多说如果服务器做的是双向验证也会报这个错误,大家根据实际情况来试,我之前就以为服务器是双向验证试了好久,双向验证方法参考:https双向认证 iOS客户端处理 建议能做单向都别给彼此找麻烦了。。。)

二、导入证书

1、直接把.der证书拉进项目
2、网上有人说要加这一步,否则证书有一定几率没加进来,不知道有没有用,为保险加一下吧。


导入证书

三、AF3.0单向验证设置

1、在你封装的网络类里添加下面代码:

- (AFSecurityPolicy*)getCustomHttpsPolicy:(AFHTTPSessionManager*)manager{
    
    //https 公钥证书配置
    
    NSString *certFilePath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"der"];
    
    NSData *certData = [NSData dataWithContentsOfFile:certFilePath];
    
    NSSet *certSet = [NSSet setWithObject:certData];
    
    AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:certSet];
    
    policy.allowInvalidCertificates = YES;// 是否允许自建证书或无效证书(重要!!!)
    
    policy.validatesDomainName = NO;//是否校验证书上域名与请求域名一致
    
    return policy;
    
}

2、在网络请求前设置一行代码,然后其他正常网络请求


AF3.0配置

四、WKWebView设置支持https

1、要实现下面代理方法,当然别忘了设置代理navigationDelegate

// https 支持
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
    
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        
        NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
        
        completionHandler(NSURLSessionAuthChallengeUseCredential,card);
        
    }
}

2、web端当然所有的接口路由都需要从http改到https

五、SDWebImage支持https

1、感谢丨Majestic灬磊 简单粗暴的方法,在此引用:

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;

options : SDWebImageAllowInvalidSSLCertificates
直接跳过验证证书就可以啦!

2、建议如果不想大改项目可以直接到 UIImageView+WebCache.m 中
把用到的几个方法改掉就好了

- (void)sd_setImageWithURL:(NSURL *)url {
    [self sd_setImageWithURL:url placeholderImage:nil options:SDWebImageAllowInvalidSSLCertificates progress:nil completed:nil];
}

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
    [self sd_setImageWithURL:url placeholderImage:placeholder options:SDWebImageAllowInvalidSSLCertificates progress:nil completed:nil];
}

到此用自建证书迁移到HTTPS就完毕了,跑了一遍整个项目暂时没有什么问题,如果apple不允许自建证书还请第一时间告知/(ㄒoㄒ)/~~

参考:
iOS 中 AFNetworking HTTPS 的使用
https双向认证 iOS客户端处理
iOS https自建证书 请求服务器 和 WKWebView
SDWebImage访问HTTPS站点获取图片资源失败解决办法

相关文章

网友评论

  • 天上飞的狒狒:按照楼主的配置以后崩溃到 AFNetworking 的
    AFHTTPSessionManager.m类的
    这个方法的
    - (void)setSecurityPolicy:(AFSecurityPolicy *)securityPolicy {
    这句中
    @throw [NSException exceptionWithName:@"Invalid Security Policy" reason:reason userInfo:nil];
  • Cherish183:你好,如果不是自签名证书,那么 webview 和wkwebview 加载https 需要适配么?
  • 羽之_HB:你好,请问我修改了SDwebImage的代码依旧没有用,依旧无法获取图片,line:29 content:这里实现了
    2017-02-05 14:48:19.129 FeiHangChuangKe[4775:221551] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
    (lldb) po url
    https://192.168.31.142/ck2/media/news_list_img/4.jpg
  • 69de80985ad6:怎样就表示已经改成https了?把allow arbitrary loads 改成NO再测试吗
  • brilliance_Liu:请问一下,我们的后台服务改成https了,但是是TLS 1.0的,ATS设置成YES可以正常访问,ATS设置成NO,无法正常访问,请问,这是属于正常的吗?还是必须要后台支持TLS1.2?
    vincent涵:@brilliance_Liu 目前搜集到信息必须TLS1.2
  • 68bf310a7804:你好,使用自建证书在分享到微信或其他平台的链接,平台如何认证证书可信,打的开分享的链接么?
    vincent涵:@泰尼号坦克 目前我这边分享出去的链接都是接口请求来再传到第三方平台的,还是http链接,所以没有问题,如果是https不太清楚,你如果遇到了请指教:grin:
  • 56d35fdf1a2a:请教一下 后台给我的是.ctr的证书 转成.cer 可以获取到(<3082.....一堆>) 但是afnetworking会报错 提示无法连接服务器-1005,The network connection was lost. 为什么呢 :sob:
    vincent涵:@来自蒙塔基的罡蛋 这个问题没遇到过……如果解决了可以和大家分享一下~
  • 蜗蜗牛在奔跑:没有禁掉ATS,相当于什么都没干啊亲
    brilliance_Liu:@L1先生 @vincent涵 是啊,我把ATS设置成YES,要不要证书都能访问啊。没有禁掉等于啥也没干啊?
    蜗蜗牛在奔跑:@vincent涵 还有就说是自建证书不能上线,是不是真的
    vincent涵:@L1先生 不知道是不是你理解的ATS和我有区别,我所谓的禁掉ATS是指允许HTTP或TLS1.2以下的https访问,从iOS9开始有的ATS就是默认只允许TSL1.2以上的HTTPS访问,禁掉之后其他才可以访问
  • 安浪创想:最便宜的证书几十块。www.anwew.com
    安浪创想: @vincent涵 你可以去百度查的,流行的证书颁布商就那么几个
    安浪创想: @vincent涵 哪里需要那么高,65元的comodo认证,国内还有免费的沃通SSL但是被封杀了。苹果官方用的是Symantec的证书,那个一千多块钱起嘛。其它的百度云有免费的,腾讯云也有免费的,百度云的是Symantec的证书,本来是1999一年的,可能是好合作吧,免费两年。不过有个条件就是只能放在百度云上购买的服务器可以免费申请,www.anwew.com这里的是自由使用的comodo也是很牛逼的。
    vincent涵:@绿血贵族 是通过CA认证的么?我们项目经理查了以下给我说通过CA认证的最便宜的证书一个域名5000一年,还给我算了一笔账,我们目前有三个域名,全部买证书就是1.5万一年,创业型公司伤不起😂
  • 王芋头先森:+ (NSSet *)certificatesInBundle:(NSBundle *)bundle {
    NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."];

    NSMutableSet *certificates = [NSMutableSet setWithCapacity:[paths count]];
    for (NSString *path in paths) {
    NSData *certificateData = [NSData dataWithContentsOfFile:path];
    [certificates addObject:certificateData];
    }

    return [NSSet setWithSet:certificates];
    }
    AF3.x加载证书是.cer,并不是.der吧
    vincent涵:@王芋头先森 der还是cer我是参考了这篇文章,而且我使用der目前没遇到什么问题,http://www.jianshu.com/p/13f6d134a59a
  • 雪_晟: 单项认证 服务器是不是 得设置 clientAuth 为false 啊
    雪_晟:@vincent涵 大神 ,升级https 后 webview 还支持http 怎么做,
    雪_晟:@vincent涵 好吧 网上上默认为true 是双向的,分不清单向认证和双向认证了
    vincent涵:@miss李manman 我们的后端说不需要设置这个,默认的,你们看情况~
  • 雪_晟:我这边拿到cer 也这么设置 可是会崩溃到安全验证里面
    vincent涵:@miss李manman 你是AF2.x吧?不好意思2.x代码有些区别,你可以参考http://www.jianshu.com/p/97745be81d64这个试试
    雪_晟:@vincent涵 不是吧 证书名字应该没错 我们两个都试了,崩溃到数组越界里 不知道还有其他原因没
    vincent涵:@miss李manman 这种崩溃一般是在路径下没找到证书,我之前遇到这种崩溃,是证书名写错了:sweat:
  • 瓜而不皮很灵性:我这边服务端给的证书直接就是cer的,去他们那边并没有.crt的证书,我现在就是报错code=-999,请教一下什么原因。
    瓜而不皮很灵性:@vincent涵 感谢您的回复
    vincent涵:@大橙子在来的路上 嗯,我和我们服务端交流,不同的后台不太一样,不一定给你.crt,最终目的都是.cer或者.der。我已知的-999错误的原因文中也写了,证书如果确定生成没问题,很有可能是服务端设置的双向绑定,你可以再和他们确认下。(不过他们给的.cer后缀名对也不一定就是对的证书,我这边刚开始就被坑了,他们用的不是最开始的根证书生成的)

本文标题:iOS 迁移到HTTPS(自建证书+单向验证+AF3.0+WKW

本文链接:https://www.haomeiwen.com/subject/tnltmttx.html