苹果官方在2017年将会强制要求使用HTTPS,当然,很多开发者可能会误解会所有在应用里面的请求都必须使用HTTPS,其实不完全是这样。苹果官方文档提供了很多细节的东西,告诉开发者如何让自己的应用适配HTTPS,本文将从原理,官方文档,以及作者的实践经验出发。详细介绍如何iOS中使用HTTS以及使用时需要注意的细节问题。
本文主要是单向验证,如果你的项目需要双向验证,看这个教程iOS–AFNetworking2.6/3.0–HTTPS客户端与服务端双向认证
不过即使是双向验证,我的建议是先先看看我这篇博客,这会对你遇到的问题有所帮助~
HTTPS基本原理
首先我们以网络传输的7个层来快速的弄懂HTTP和HTTPS的基本区别。
HTTP传输:
HTTPS传输:
一眼就可以看出区别了吧,其实HTTPS就是在HTTP的基础上,在传输层和会话层之间了一个SSL层,简单来说都作用是负责数据的加解密,从而保证了数据都安全。
SSL(Security Socket Layer 安全套接层) 最初1994年Netscape开发,专门用于保护Web通讯.保护浏览器和服务器之间的通信,在客户和服务器之间提供服务器鉴别、可选客户鉴别和加密通信信道。使用TCP提供一种可靠的端对端的安全服务。
版本和历史
- 1.0,不成熟
- 2.0,基本上解决了Web通讯的安全问题
Microsoft公司发布了PCT(Private Communication Technology),并在IE中支持 - 3.0,1996年发布,增加了一些算法,修改了一些缺陷
TLS 1.0(Transport Layer Security传输层安全协议, 也被称为SSL 3.1),1997年IETF发布了Draft,同时,Microsoft宣布放弃PCT,与Netscape一起支持TLS 1.0
1999年,发布RFC 2246(The TLS Protocol v1.0)
苹果现在要求使用的是TLS1.2。待会我会继续提到这个问题。
SSL的主要功能
- 客户端验证服务器
- 客户段与服务器选择彼此支持的算法
- 服务器验证客户端(可选)
- 使用公开密钥算法产生共享的密钥
当然,HTTPS比较难以理解的还是它的协议,尤其是握手协议,考虑到篇幅的原因,这里不过多的讲解。
官方相关文档解读
App Transport Security (ATS)在iOS 9.0之后就默认开启了。也就是我吗之前请求HTTPS的时候NSAllowsArbitraryLoads
这个key的值默认设置为NO
了,而且这个键现在在NSAppTransportSecurity
字典的第一层。
NSAppTransportSecurity : Dictionary {
NSAllowsArbitraryLoads : Boolean
NSAllowsArbitraryLoadsForMedia : Boolean
NSAllowsArbitraryLoadsInWebContent : Boolean
NSAllowsLocalNetworking : Boolean
NSExceptionDomains : Dictionary {
<domain-name-string> : Dictionary {
NSIncludesSubdomains : Boolean
NSExceptionAllowsInsecureHTTPLoads : Boolean
NSExceptionMinimumTLSVersion : String
NSExceptionRequiresForwardSecrecy : Boolean // Default value is YES
NSRequiresCertificateTransparency : Boolean
}
}
}
除了NSExceptionRequiresForwardSecrecy
默认的值时YES
。其它的默认的值都是NO
。
NSAppTransportSecurity
字典分两个层级配置,前面四个
NSAllowsArbitraryLoads
,NSAllowsArbitraryLoadsForMedia
,
NSAllowsArbitraryLoadsInWebConten
, NSAllowsLocalNetworking
是对整个APP全局的配置。如果我们需要对某个域名有区分的对待就需要在NSExceptionDomains
里面进行相应的配置。
NSAllowsArbitraryLoads
设置为YES
的话,就会使得除了开发者在NSExceptionDomains
里面配置的域名以外所有的网络连接不受限制。
如果你设置为YES
的话,需要在提审核的时候说明这样做的原因。
NSAllowsArbitraryLoadsForMedia
设置为YES
的话,所有在APP里面使用AV Foundation framework加载的视频都不会被限制。如果不设置的话,就仅用于加载已加密的媒体,例如由FairPlay或安全HLS保护的文件,并且不包含个人信息。
如果你设置为YES
的话,同样也是需要在提审核的时候说明你这样做的原因。
NSAllowsArbitraryLoadsInWebContent
如果你设置为YES
的话,系统会禁用对来自Web视图的请求的所有ATS限制,也就是你的WebView的请求不不一定需要HTTPS,APP就可以使用嵌入式浏览器来显示任意内容,但是应用的其他部分还是需要用ATS。
如果你设置为YES
的话,同样也是需要在提审核的时候说明你这样做的原因。
NSAllowsLocalNetworking
设置为YES
的话就允许加载本地资源。
NSExceptionDomains
NSExceptionDomains
其实是相当于NSAllowsArbitraryLoads
的一个子集。后者是全局的作用,而前者主要是用于对某些域名的限制作用。他的主要作用其实就是用于们自签名的证书,具体使用细节我会在后面具体介绍。
NSExceptionDomains
字典里面各键的值意义如下。
- NSIncludesSubdomains
默认为NO
,如果设置为YES
,则表示当前设置域名的所有子域名也使用同样的配置
- NSExceptionAllowsInsecureHTTPLoads
允许不安全的HTTP请求,这里所谓的不安全,不代表改变了 Transport Layer Security (TLS)或是事HTTPS的请求。所谓的不安全主要是因为使用自签名的证书,没有经过CA认证所以苹果并不知道是不是安全的,如果开发者允许那么苹果也允许加载。
设置为YES
,在审核的时候你需要说明原因
- NSExceptionMinimumTLSVersion
这个属性用于表面你的HTTPS的TLS版本,因为苹果默认是支持TLS1.2,所以如果你使用了较低的版本你你需要自己指明。
设置为这个键后,在审核的时候你也需要说明原因。
NSExceptionRequiresForwardSecrecy
如果设置为NO,则允许不支持完全前向保密(PFS)的TLS密码(对于指定的域名)。 默认值为YES。关于完全正向保密,可以看这篇文章TLS完美前向保密(perfect forward secrecy)翻译。NSRequiresCertificateTransparency
如果设置为YES,则对于命名域的服务器证书,需要有效的签名证书透明度的时间戳。 默认值为NO。
以上这么多内容,对于iOS开发者来自说最重要的信息就是有五个键,如果开发者不使用默认值,则需要在审核的时候进行说明。这五个键是
NSAllowsArbitraryLoads
NSAllowsArbitraryLoadsForMedia
NSAllowsArbitraryLoadsInWebContent
NSExceptionAllowsInsecureHTTPLoads
NSExceptionMinimumTLSVersion
这对于嵌入了很多网页或是视频的APP来说感觉会比较麻烦一些。