https:linux
连接地址:http://op.baidu.com/2015/04/https-s01a01/ http://op.baidu.com/2015/04/https-s01a02/git
https = http+tls算法
目前经常使用的 HTTP 协议是 HTTP1.1,经常使用的 TLS 协议版本有以下几个:TLS1.2, TLS1.1, TLS1.0 和 SSL3.0。其中 SSL3.0 因为 POODLE 攻击已经被证实不安全,但统计发现依然有不到 1% 的浏览器使用 SSL3.0。TLS1.0 也存在部分安全漏洞,好比 RC4 和 BEAST 攻击。chrome
TLS1.2 和 TLS1.1 暂时没有已知的安全漏洞,比较安全,同时有大量扩展提高速度和性能,推荐你们使用windows
加密算法通常分为两种,对称加密和非对称加密。所谓对称加密(也叫密钥加密)就是指加密和解密使用的是相同的密钥。而非对称加密(也叫公钥加密)就是指加密和解密使用了不一样的密钥。浏览器
图 2 对称加密缓存
图 3 非对称加密安全
对称内容加密强度很是高,通常破解不了。但存在一个很大的问题就是没法安全地生成和保管密钥。假如客户端软件和服务器之间每次会话都使用固定的,相同的密钥加密和解密,确定存在很大的安全隐患。若是有人从客户端端获取到了对称密钥,整个内容就不存在安全性了,并且管理海量的客户端密钥也是一件很复杂的事情。服务器
非对称加密主要用于密钥交换(也叫密钥协商),可以很好地解决这个问题。浏览器和服务器每次新建会话时都使用非对称密钥交换算法协商出对称密钥,使用这些对称密钥完成应用数据的加解密和验证,整个会话过程当中的密钥只在内存中生成和保存,并且每一个会话的对称密钥都不相同(除非会话复用),中间者没法窃取。网络
非对称密钥交换很安全,但同时也是 HTTPS 性能和速度严重下降的“罪魁祸首”。想要知道 HTTPS 为何影响速度,为何消耗资源,就必定要理解非对称密钥交换的整个过程。
非对称加密相比对称加密更加安全,但也存在两个明显缺点:
1, CPU 计算资源消耗很是大。一次彻底 TLS 握手,密钥交换时的非对称解密计算量占整个握手过程的 90% 以上。而对称加密的计算量只至关于非对称加密的 0.1%,若是应用层数据也使用非对称加解密,性能开销太大,没法承受。
2, 非对称加密算法对加密内容的长度有限制,不能超过公钥长度。好比如今经常使用的公钥长度是 2048 位,意味着待加密内容不能超过 256 个字节。
因此公钥加密目前只能用来做密钥交换或者内容签名,不适合用来作应用层传输内容的加解密。
非对称密钥交换算法是整个 HTTPS 得以安全的基石,充分理解非对称密钥交换算法是理解 HTTPS 协议和功能的关键。
身份认证:
身份认证主要涉及到 PKI 和数字证书。一般来说 PKI(公钥基础设施)包含以下部分:
申请一个受信任的数字证书一般有以下流程:
1, 终端实体生成公私钥和证书请求。
2, RA 检查实体的合法性。若是我的或者小网站,这一步不是必须的。
3, CA 签发证书,发送给申请者。
4, 证书更新到 repository,终端后续从 repository 更新证书,查询证书状态等。
目前百度使用的证书是 X509v3 格式,由以下三个部分组成:
1, tbsCertificate(to be signed certificate 待签名证书内容),这部分包含了 10 个要素,分别是版本号,序列号,签名算法标识,发行者名称,有效期,证书主体名,证书主体公钥信息,发行商惟一标识,主体惟一标识,扩展等。
2, signatureAlgorithm,签名算法标识,指定对 tbsCertificate 进行签名的算法。
3, signaturValue(签名值),使用 signatureAlgorithm 对 tbsCertificate 进行计算获得签名值。
数字证书有两个做用:
1, 身份受权。确保浏览器访问的网站是通过 CA 验证的可信任的网站。
2, 分发公钥。每一个数字证书都包含了注册者生成的公钥。在 SSL 握手时会经过 certificate 消息传输给客户端。好比前文提到的 RSA 证书公钥加密及 ECDHE 的签名都是使用的这个公钥。
申请者拿到 CA 的证书并部署在网站服务器端,那浏览器发起握手接收到证书后,如何确认这个证书就是 CA 签发的呢?怎样避免第三方伪造这个证书?
答案就是数字签名(digital signature)。数字签名是证书的防伪标签,目前使用最普遍的 SHA-RSA 数字签名的制做和验证过程以下:
1, 数字签名的签发。首先是使用哈希函数对待签名内容进行安全哈希,生成消息摘要,而后使用 CA 本身的私钥对消息摘要进行加密。
2, 数字签名的校验。使用 CA 的公钥解密签名,而后使用相同的签名函数对待签名证书内容进行签名并和服务端数字签名里的签名内容进行比较,若是相同就认为校验成功。
图 8 数字签名生成及校验
这里有几点须要说明:
在介绍速度优化策略以前,先来看下 HTTPS 对速度有什么影响。影响主要来自两方面:
HTTPS 首次请求须要的网络耗时解释以下:
1, 三次握手创建 TCP 链接。耗时一个 RTT。
2, 使用 HTTP 发起 GET 请求,服务端返回 302 跳转到 https://www.baidu.com。须要一个 RTT 以及 302 跳转延时。
a) 大部分状况下用户不会手动输入 https://www.baidu.com 来访问 HTTPS,服务端只能返回 302 强制浏览器跳转到 https。
b) 浏览器处理 302 跳转也须要耗时。
3, 三次握手从新创建 TCP 链接。耗时一个 RTT。
a) 302 跳转到 HTTPS 服务器以后,因为端口和服务器不一样,须要从新完成三次握手,创建 TCP 链接。
4, TLS 彻底握手阶段一。耗时至少一个 RTT。
a) 这个阶段主要是完成加密套件的协商和证书的身份认证。
b) 服务端和浏览器会协商出相同的密钥交换算法、对称加密算法、内容一致性校验算法、证书签名算法、椭圆曲线(非 ECC 算法不须要)等。
c) 浏览器获取到证书后须要校验证书的有效性,好比是否过时,是否撤销。
5, 解析 CA 站点的 DNS。耗时一个 RTT。
a) 浏览器获取到证书后,有可能须要发起 OCSP 或者 CRL 请求,查询证书状态。
b) 浏览器首先获取证书里的 CA 域名。
c) 若是没有命中缓存,浏览器须要解析 CA 域名的 DNS。
6, 三次握手创建 CA 站点的 TCP 链接。耗时一个 RTT。
a) DNS 解析到 IP 后,须要完成三次握手创建 TCP 链接。
7, 发起 OCSP 请求,获取响应。耗时一个 RTT。
8, 彻底握手阶段二,耗时一个 RTT 及计算时间。
a) 彻底握手阶段二主要是密钥协商。
9, 彻底握手结束后,浏览器和服务器之间进行应用层(也就是 HTTP)数据传输。
固然不是每一个请求都须要增长 7 个 RTT 才能完成 HTTPS 首次请求交互。大概只有不到 0.01% 的请求才有可能须要经历上述步骤,它们须要知足以下条件:
1, 必须是首次请求。即创建 TCP 链接后发起的第一个请求,该链接上的后续请求都不须要再发生上述行为。
2, 必需要发生彻底握手,而正常状况下 80% 的请求能实现简化握手。
3, 浏览器须要开启 OCSP 或者 CRL 功能。Chrome 默认关闭了 ocsp 功能,firefox 和 IE 都默认开启。
4, 浏览器没有命中 OCSP 缓存。Ocsp 通常的更新周期是 7 天,firefox 的查询周期也是 7 天,也就说是 7 天中才会发生一次 ocsp 的查询。
5, 浏览器没有命中 CA 站点的 DNS 缓存。只有没命中 DNS 缓存的状况下才会解析 CA 的 DNS。
HTTPS 和 HTTP 使用 TCP 协议进行传输,也就意味着必须经过三次握手创建 TCP 链接,但一个 RTT 的时间内只传输一个 syn 包是否是太浪费?能不能在 syn 包发出的同时捎上应用层的数据?实际上是能够的,这也是 tcp fast open 的思路,简称 TFO。具体原理能够参考 rfc7413。
遗憾的是 TFO 须要高版本内核的支持,linux 从 3.7 之后支持 TFO,可是目前的 windows 系统还不支持 TFO,因此只能在公司内部服务器之间发挥做用。
前面提到过将用户 HTTP 请求 302 跳转到 HTTPS,这会有两个影响:
1, 不安全,302 跳转不只暴露了用户的访问站点,也很容易被中间者支持。
2, 下降访问速度,302 跳转不只须要一个 RTT,浏览器执行跳转也须要执行时间。
因为 302 跳转事实上是由浏览器触发的,服务器没法彻底控制,这个需求致使了 HSTS 的诞生:
HSTS(HTTP Strict Transport Security)。服务端返回一个 HSTS 的 http header,浏览器获取到 HSTS 头部以后,在一段时间内,无论用户输入www.baidu.com仍是http://www.baidu.com,都会默认将请求内部跳转成https://www.baidu.com。
Chrome, firefox, ie 都支持了 HSTS(http://caniuse.com/#feat=stricttransportsecurity)。
Session resume 顾名思义就是复用 session,实现简化握手。复用 session 的好处有两个:
1, 减小了 CPU 消耗,由于不须要进行非对称密钥交换的计算。
2, 提高访问速度,不须要进行彻底握手阶段二,节省了一个 RTT 和计算耗时。
2.4 使用http2