苹果公司在2016的开发者大会上宣布:到2017年,所有的iOS应用都必须使用HTTPS与服务器进行通信。iOS开发者应该都不会对这个决定感到惊讶,因为自iOS9就已经引入了ATS(应用传输安全App Transport Security)特性,该特性对应用的安全传输做出了以下要求:
1.The protocol Transport Security Layer (TLS) must be at least version 1.2.
2.Connection ciphers are limited to those that provide forward secrecy (see the list of ciphers below.)
3.Certificates must use at least an SHA256 fingerprint with either a 2048 bit or greater RSA key, or a 256 bit or greater Elliptic-Curve (ECC) key.
不符合以上条件的任意一项,网络请求将会被中断并返回空值。 不明觉厉地找到了一个翻译版:
苹果ATS对HTTPS证书的要求
启用ATS必须符合以下标准,不满足条件的HTTPS证书,ATS都会拒绝连接:
* 服务器所有的连接使用TLS1.2以上版本
* HTTPS证书必须使用SHA256以上哈希算法签名
* HTTPS证书必须使用RSA 2048位或ECC 256位以上公钥算法
* 使用前向加密技术
虽然苹果官方最近发布声明说最后期限延迟了,不过还是未雨绸缪为好,本文就先对https相关的一些基本概念进行阐述。
HTTPS的原理及运行机制
HTTPS 以及SSL/TSL
什么是SSL?
SSL(Secure Sockets Layer, 安全套接字层),因为原先互联网上使用的 HTTP 协议是明文的,存在很多缺点,比如传输内容会被偷窥(嗅探)和篡改。 SSL 协议的作用就是在传输层对网络连接进行加密。
何为TLS?
到了1999年,SSL 因为应用广泛,已经成为互联网上的事实标准。IETF 就在那年把 SSL 标准化。标准化之后的名称改为 TLS(Transport Layer Security,传输层安全协议)。SSL与TLS可以视作同一个东西的不同阶段
HTTPS
简单来说,HTTPS = HTTP + SSL/TLS, 也就是 HTTP over SSL 或 HTTP over TLS,这是后面加 S 的由来 。
HTTPS和HTTP异同:HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。HTTP的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。
首先,不使用SSL/TLS的HTTP通信,是不加密的通信,这显然不能保证客户的信息安全。在文章iOS开发中使用keyChain保存用户密码中,辛辛苦苦地将用户名密码能够安全地存储在keyChain中(不越狱的前提下),但是如果用户名密码就这样明文地发送出去,一旦被截获,后果可想而知。当然,我们很自然地就会想到将用户密码字符串进行MD5加密后,再通过网络发送给服务器,比如:
NSString *sourceStr = [NSString stringWithFormat:@"attach=iOS&chartset=utf-8&format=json&partner=google&userid=%@&password=%@”,userid,password];
NSString *signStr = [NSString md5String:sourceStr];
但即便如此也不能保证安全,因为存在碰撞攻击。关于碰撞攻击,可以阅读安全科普:密码学之碰撞攻击一文。
于是,为了实现通信的安全,SSL/TLS协议采用公钥加密法,其运行的基本流程是:
* 客户端向服务器端索要并验证公钥;
* 双方协商生成"对话密钥";
* 双方采用"对话密钥"进行加密通信。
其中,第1和2步被称为握手阶段。握手阶段的细节这里就不赘述,我们只需要知道,通过握手阶段,客户端和服务器端主要交换了3个信息:
1、数字证书。该信息是我们进行开发需要关注的!数字证书包含了公钥等信息,一般由服务器发给客户端,接收方通过验证这个证书是不是由信赖的CA签发,或者与本地的证书相对比,来判断证书是否可信;假如需要双向验证,则服务器和客户端都需要发送数字证书给对方验证;
2、3个随机数。3个随机数是用于生成对话密钥的,我们不需要关心这细节;解释如下(可忽略):
首先客户端先发第一个随机数N1,然后服务器回了第二个随机数N2(这个过程同时把之前提到的证书发给客户端),这两个随机数都是明文的;而第三个随机数N3(这个随机数被称为Premaster secret),客户端用数字证书的公钥进行非对称加密,发给服务器;而服务器用只有自己知道的私钥来解密,获取第三个随机数。只有,服务端和客户端都有了三个随机数N1+N2+N3,然后两端就使用这三个随机数来生成“对话密钥”,在此之后的通信都是使用这个“对话密钥”来进行对称加密解密。因为这个过程中,服务端的私钥只用来解密第三个随机数,从来没有在网络中传输过,这样的话,只要私钥没有被泄露,那么数据就是安全的。
3、加密通信协议。客户端和服务器端通信需要采取同样的加密通信协议,我们也不需要太关注。
SSL四次握手的另一种解释:
浏览器将通过网络发送请求安全会话的消息(通常请求以 https 而非 http 开头的 URL)。
1.服务器通过发送其证书(包括公钥)进行响应。
2.浏览器将检验服务器的证书是否有效,并检验该证书是否是由其证书位于浏览器的数据库中的(并且是可信的)CA 所签发的。它还将检验 CA 证书是否已过期。
3.如果证书有效,浏览器将生成一个==一次性的、唯一的==会话密钥,并使用服务器的公钥对该会话密钥进行加密。然后,浏览器将把加密的会话密钥发送给服务器,这样服务器和浏览器都有一份会话密钥。
4.服务器可以使用其专用密钥对消息进行解密,然后恢复会话密钥。
握手之后,即表示客户端已验证了 Web 站点的身份,并且只有该客户端和 Web 服务器拥有会话密钥副本。从现在开始,客户机和服务器便可以使用该会话密钥对彼此间的所有通信进行加密。这样就确保了客户机和服务器之间的通信的安全性。
上面是一般也是应用最普遍的单向验证方式,由浏览器(客户端)来验证服务端的合法性;其实也可以做双向验证,服务器也可以验证浏览器(客户端)的合法性,不过一般使用在银行业务上,比如U盾之类。我们现在关注普遍的单向验证方式的应用。
数字证书与公钥基础设施
刚才已经了解到HTTPS是基于公钥加密法,而公钥基础设施(PKI)就是一种遵循标准的利用公钥加密技术为电子商务的开展提供一套安全基础平台的技术和规范。完整的PKI系统拥有权威认证机构(CA)、数字证书库、密钥备份及恢复系统、证书作废系统、应用接口(API)等基本构成部分,其中权威认证机构CA将是我们需要打交道的部门。
该系统的逻辑关系可以这样理解:
1、申请人向CA提交申请材料;
2、数字证书是由证书认证机构(CA)对证书申请者真实身份验证之后,用CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机构的公章)后形成的一个数字文件。CA完成签发证书后,会将证书发布在CA的证书库(目录服务器)中,任何人都可以查询和下载,因此数字证书和公钥一样是公开的。
3、每个证书持有人都有一对公钥和私钥,这两把密钥可以互为加解密。公钥是公开的,不需要保密,而私钥是由证书持有人自己持有,并且必须妥善保管和注意保密。
简单地说,数字证书就是经过CA认证过的公钥,而私钥一般情况都是由证书持有者在自己本地生成的,由证书持有者自己负责保管。
至此,逻辑链条就和SSL/TLS协议运行机制衔接上了:申请人事先通过向CA申请,已经有了公钥和私钥。客户端向服务器请求,能够得到包含公钥的数字证书。得到公钥后,双方就按照上节中运行的基本流程生成对话密钥,而后开始加密通信。
如何验证数字证书是由CA签发而非伪造的,请移步:iOS安全系列之一:HTTPS
搭建一个HTTPS服务器。根据网络上的资料,可知有两种方式来搭建HTTPS服务器:
一种是创建证书请求,然后到权威机构认证,随之配置到服务器;
一种是自建证书,然后配置给服务器。
第一种方式搭建的HTTPS服务器是最优的。建立网站的话,直接就会被信任。而服务器作为移动端app的服务器时,也不需要为ATS做过多的适配。虽然说权威的机构认证都是需要钱的,但是如今也不乏存在免费的第三方认证机构;
第二种方式搭建的HTTPS服务器,对于网站来说完全不可行,用户打开时直接弹出一个警告提醒,说这是一个不受信任的网站,让用户是否继续,体验很差,而且让用户感觉网站不安全。对于移动端来说,在iOS9出现之前,这个没什么问题,但是在iOS9出来之后,第二种方式是通不过ATS特性,需要在info.plist文件中将App Transport Security Settings中的Allow Arbitrary Loads设置为YES才行。
参考文章: