Xcode
https证书
https包括两种认证,单向认证和双向认证。单向认证只要求服务器部署了ssl证书就行,任何客户端都可以去访问,这样就能确保客户端连接的是真实的服务端。而双向认证则是服务端需要客户端提供身份认证,只能是服务端允许的客户端才能去访问,安全性相对于要高。也就是说,单项认证,我们iOS工程里要放一个证书,而双向认证,我们的工程中要放两个证书。
这里,我先用单向验证做下示范,这里面的原理很简单。简单得说就是客户端向服务器发起需求 ,服务器把证书发给客户端,客户端验证下证书是否合法,然后用证书的数据加密传输数据给服务器,服务器解密。
我这里是用AFNetworking做网络请求。首先我们把证书导入到工程中,注意,虽然AFN会自动获取我们的证书路径,但是我建议要在bundle添加一下,因为有时候会获取不到证书路径,所以,还是打印一下路径比较靠谱。 NSString *cerPath = [[NSBundle mainBundle] pathForResource:@'证书' ofType:@'cer']; NSLog(@'路径:%@', cerPath);
下面要介绍下证书的验证模式 AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];1.AFSSLPinningModeNone 不做任何验证,只要服务器返回了证书就通过2.AFSSLPinningModePublicKey 只验证公钥部分,只要公钥部分一致就验证通过,如图所示,红色框起来的部分只要一致就通过3.AFSSLPinningModeCertificate除了公钥外,其他能容也要一致才能通过验证。这里注意,如果是AFSSLPinningModeNone这种验证模式,那就根本不需要往工程中导入证书。后两种才需要导入证书。
接着,设置AFSecurityPolicy的属性: //是否需要自建证书,默认YES securityPolicy.allowInvalidCertificates = YES; // 是否验证域名。默认为YES。//假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。//置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。//如置为NO,建议自己添加对应域名的校验逻辑。 securityPolicy.validatesDomainName = NO;
走到这一步,代码设置就完成了,接着我们学习info.plist中的NSAppTransportSecurity键值自定义网络安全策略。对于使用 iOS9.0, OS X v10.11 SDK 及以上的 app 来说,ATS(App Transport Security)默认开启,NSAllowsArbitraryLoads是字典NSAppTransportSecurity的根键,默认值NO。在启用 ATS 的情况下,所有的 HTTP 请求必须为 HTTPS(RFC 2818) 连接。任何不安全的 HTTP 请求都将失败。ATS 使用 TLS(Transport Layer Security)。下图是字典NSAppTransportSecurity的总体结构,所有键都是非必填项:
我们主要用这个NSExceptionDomains键值对,为一个或多个域名单独配置 ATS。向Info.plist中添加这一主键:这意味着之前使用主键所做的设置,对于这个域名来说,已经无效。这个键对应一个字典,包含以下子键:
如果你用的是付费的公信机构颁发的证书,标准的https,那么无论你用的是AF还是NSUrlSession,什么都不用做,代理方法也不用实现。你的网络请求就能正常完成。