什么是HTTPS
HTTPS就是在安全的传输层发送HTTP,HTTP + TLS/SSL。
HTTPS,客户端首先打开一条到web服务器端口443的连接,建立了TCP连接,客户端和服务器就会初始化SSL层,对加密参数进行沟通,交换密钥,握手完成后,SSL初始化完成,客户端将请求报文发送给安全层。
用途:
-
防止窃取,内容加密,浏览器到服务器的内容都是以加密形式传输,中间者无法直接查看原始内容;
-
防止冒充,配备身份证书,保证用户访问的真实的站点,即使被 DNS 劫持到了第三方站点,也会提醒用户没有访问真实站点,有可能被劫持;
-
防止篡改,具有校验机制,防止内容被第三方冒充或者篡改。
TLS/SSL
TLS(Transport Layer Security)传输层安全协议。它的前身是SSL(Secure Sockets Layer)安全套接层。基本思路是采用公钥加密法,用于在两个通信应用程序之间提供保密性和数据完整性。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。
常用TLS版本:TLS1.2和TLS1.1(TLS1.0、SSL3.0和SSL2.0已经被证实不安全)。
TLS协议组成
TLS 协议主要有五部分:应用数据层协议,握手协议,报警协议,加密消息确认协议,心跳协议。由 record 协议传输。
TLS握手
0 ms:TLS运行在TCP基础之上,这意味着我们必须首先完成TCP 三次握手,这需要一个完整的来回交互(RTT)。
56 ms:TCP连接建立后,先向服务器发出加密通信的请求(Client Hello请求)
发送内容:
支持的协议版本;
支持的加密列表(比如Rsa);
加密随机数;
其他TLS选项。
84 ms:服务器回应(Server Hello),服务器回应TLS协议版本
回应内容:
一个服务器生成的随机数(用于加密密钥);
确认使用的加密方法;
服务器证书;
其他TLS选项。
112 ms:客户端回应(Client Key Exchange),验证服务器证书通过(否则给予警告)。假设双方协商好一个共同的TLS版本和加密算法,客户端使用服务器提供的证书,生成新的对称密钥,并用服务器的公钥进行加密,并告诉服务器切换到加密通信流程。到现在为止,所有被交换的数据都是以明文方式传输,除了对称密钥外,它采用的是服务器端的公钥加密。
回应内容:
一个随机数。该随机数用服务器公钥加密,防止被窃听;
编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送;
客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。
140 ms:服务器的最后回应(Server Finish),服务器用自己的私钥解密客户端发过来的对称密钥,并通过验证MAC检查消息的完整性,并返回给客户端一个加密的“Finished”的消息。
回应内容:
编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送;
服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。
168 ms:客户端采用对称密钥解密消息,并验证MAC,加密隧道建立。
Client Server
ClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
TLS加密 Secret Keys
PreMaster secret
PreMaster secret是在客户端使用RSA或者Diffie-Hellman等加密算法生成的。它将用来跟服务端和客户端在Hello阶段产生的随机数结合在一起生成Master secret。
Master secret
Session Secret
RSA 发挥的关键作用就是对 PreMaster secret 进行了加密和解密
TLS/SSL的功能实现主要依赖于三类基本算法:散列函数 Hash、对称加密和非对称加密。
TLS延迟
HTTP耗时 = TCP握手
HTTPs耗时 = TCP握手 + TLS/SSL握手
命令行工具curl有一个w参数,可以用来测量TCP握手和SSL握手的具体耗时
curl -w "TCP handshake: %{time_connect}, SSL handshake: %{time_appconnect}\n" -so /dev/null https://www.baidu.com
TCP handshake: 0.021, SSL handshake: 0.076
w参数表示指定输出格式,time_connect变量表示TCP握手的耗时,time_appconnect变量表示SSL握手的耗时
HTTPS对速度的影响:
-
协议交互所增加的网络 RTT(round trip time)
-
加解密相关的计算耗时
网络耗时
HTTP 首个请求的网络耗时
HTTPS 首个请求的网络耗时
计算耗时
1、浏览器计算耗时
-
RSA 证书签名校验,浏览器需要解密签名,计算证书哈希值。如果有多个证书链,浏览器需要校验多个证书。
-
RSA 密钥交换时,需要使用证书公钥加密 premaster。耗时比较小,但如果手机性能比较差,可能也需要 1ms 的时间。
-
ECC 密钥交换时,需要计算椭圆曲线的公私钥。
-
ECC 密钥交换时,需要使用证书公钥解密获取服务端发过来的 ECC 公钥。
-
ECC 密钥交换时,需要根据服务端公钥计算 master key。
-
应用层数据对称加解密。
-
应用层数据一致性校验。
2、服务端计算耗时
-
RSA 密钥交换时需要使用证书私钥解密 premaster。这个过程非常消耗性能。
-
ECC 密钥交换时,需要计算椭圆曲线的公私钥。
-
ECC 密钥交换时,需要使用证书私钥加密 ECC 的公钥。
-
ECC 密钥交换时,需要根据浏览器公钥计算共享的 master key。
-
应用层数据对称加解密。
-
应用层数据一致性校验。
身份认证
身份认证主要涉及到 PKI 和数字证书。通常来讲 PKI(公钥基础设施)包含如下部分:
-
End entity:终端实体,可以是一个终端硬件或者网站。
-
CA:证书签发机构。
-
RA:证书注册及审核机构。比如审查申请网站或者公司的真实性。
-
CRL issuer:负责证书撤销列表的发布和维护。
-
Repository:负责数字证书及 CRL 内容存储和分发.
CA,Catificate Authority,它的作用就是提供证书(即服务器证书,由域名、公司信息、序列号和签名信息组成)加强服务端和客户端之间信息交互的安全性,以及证书运维相关服务。
HTTPS优化
访问速度优化
(1)Tcp fast open
TCP Fast Open (TFO) is an experimental update to TCP that enables data to be exchanged safely during TCP’s connection handshake。
详细参考:rfc7413
(2)HSTS
将用户 HTTP 请求 302 跳转到 HTTPS
-
不安全,302 跳转不仅暴露了用户的访问站点,也很容易被中间者支持。
-
降低访问速度,302 跳转不仅需要一个 RTT,浏览器执行跳转也需要执行时间。
HSTS(HTTP Strict Transport Security),Declare that a website is only accessible over a secure connection (HTTPS)。
服务端返回一个 HSTS 的 http header,浏览器获取到 HSTS 头部之后,在一段时间内,不管用户输入www.baidu.com还是http://www.baidu.com,都会默认将请求内部跳转成https://www.baidu.com。
浏览器支持Strict Transport Security
(3)Session resume
复用 session,实现简化握手
Session cache
Session cache 的原理是使用 client hello 中的 session id 查询服务端的 session cache, 如果服务端有对应的缓存,则直接使用已有的 session 信息提前完成握手,称为简化握手。
缺点:
-
需要消耗服务端内存来存储 session 内容
-
nginx,apache 只支持单机多进程间共享缓存,不支持多机间分布式缓存
Session ticket
The ticket is created by a TLS server and sent to a TLS client. The TLS client presents the ticket to the TLS server to resume a session.
Client Server
ClientHello
(SessionTicket extension) -------->
ServerHello
(empty SessionTicket extension)
NewSessionTicket
[ChangeCipherSpec]
<-------- Finished
[ChangeCipherSpec]
Finished -------->
Application Data <-------> Application Data
缺点:
-
只是 TLS 协议的一个扩展特性,目前的支持率不是很广泛
-
需要维护一个全局的 key 来加解密,需要考虑 KEY 的安全性和部署效率
(4)Ocsp stapling
Ocsp 全称在线证书状态检查协议 (rfc6960),用来向 CA 站点查询证书状态,比如是否撤销。通常情况下,浏览器使用 OCSP 协议发起查询请求,CA 返回证书状态内容,然后浏览器接受证书是否可信的状态。
这个过程非常消耗时间,因为 CA 站点有可能在国外,网络不稳定,RTT 也比较大。那有没有办法不直接向 CA 站点请求 OCSP 内容呢?ocsp stapling 就能实现这个功能。
详细介绍参考 RFC6066 第 8 节。简述原理就是浏览器发起 client hello 时会携带一个 certificate status request 的扩展,服务端看到这个扩展后将 OCSP 内容直接返回给浏览器,完成证书状态检查。
由于浏览器不需要直接向 CA 站点查询证书状态,这个功能对访问速度的提升非常明显。
Nginx 目前已经支持这个 ocsp stapling file,只需要配置 ocsp stapling file 的指令就能开启这个功能:
ssl_stapling on;ssl_stapling_file ocsp.staple;
(5)False start
False start 的原理就是在 client_key_exchange 发出时将应用层数据一起发出来,能够节省一个 RTT。
False start 依赖于 PFS(perfect forward secrecy 完美前向加密),而 PFS 又依赖于 DHE 密钥交换系列算法(DHE_RSA, ECDHE_RSA, DHE_DSS, ECDHE_ECDSA),所以尽量优先支持 ECDHE 密钥交换算法实现 false start。
(6)使用 SPDY 或者 HTTP2
支持多路复用,能将多个 HTTP 请求在同一个连接上一起发出去
HTTPS 计算性能优化
-
优先使用 ECC
-
使用最新版的 openssl
-
硬件加速方案
-
TLS 远程代理计算
Tools
wiresharp
问题记录
-
使用TLS1.2版本,需要升级openssl到1.0.1版本
-
curl库需要升级到7.34以上版本
-
PHP编译需要指定curl目录