https原理学习笔记

什么是https

https = http + tls/ssl
https是使用tls/ssl加密的http协议。http是明文传输,存在信息窃听、信息篡改和信息劫持的风险,而tls/ssl协议具有身份验证、完整性校验和信息加密的功能,所以可以避免这些问题。

tls/ssl协议原理

tls/ssl协议主要依赖三种算法:散列函数hash、对称加密算法和非对称加密算法。非对称加密实现身份认证和密钥协商,对称加密算法使用协商的密钥对数据进行加密,散列函数对信息进行完整性校验。

  • 常见的散列函数有md5、sha256等,该类函数的特点是单向不可逆、对输入敏感、输出长度固定,对不同的输入有不同且长度相等的输出。它的使用方法主要是发送方对信息用散列函数生成一个摘要,接收方对信息用相同的散列函数也生成一个摘要,如果两个摘要相同,则数据完整。
  • 对称加密,常见的算法有aes、des等,该算法用相同的密钥加密或者解密信息。实现方法较简单,但是如何传递用来加解密的密钥是个问题,如果明文传输密钥,会有泄漏的风险。对称加密算法的通信方式是一对一的,服务器和客户端需要共享相同的密码,所以从信息安全的角度,不同的客户端必须有不同的密钥。
  • 非对称加密,常见的算法有rsa、dh等。服务端有两个密钥,公钥是公开的,私钥只有自己知道。信息只能被公钥加密,私钥解密或者私钥加密,公钥解密。因为掌握相同公钥的客户端无法解密信息,所以非对称加密的通信方式可以是一对多。客户端加密的信息只有服务器可以解密,服务器加密的信息,所有客户端都可以解密。非对称加密的复杂度比对称加密要复杂得多,所以一般不用来做普通通信。

结合这三种算法的特点,tls的工作原理简单来说是这样:用散列函数对信息生成摘要,用非对称加密实现身份认证和对称加密密钥的协商,再用对称加密对信息和摘要进行加密传输。

证书

rsa身份认证的隐患

在身份认证和密钥协商阶段,我们常用rsa算法,公钥是由服务器提供的,但是公钥里没有服务器信息,所以rsa算法无法确定公钥的所属者。
https原理学习笔记_第1张图片
如上图所示,如果有第三方截获了客户端发往服务器的请求,第三方将自己的公钥给了客户端,与客户端直接建立https通信。获取到客户端信息之后,第三方再可以想服务器建立https通信,进行信息篡改。

ca和证书

为了解决上述问题,需要一个方法来证明公钥是服务器自己的,为此引入了权威的第三方机构ca,ca负责合适公钥拥有者的信息,并为其办法证书,同时ca也为使用者提供证书验证服务。
一个ca证书里包含签发机构、有效期、域名、申请者的组织信息和个人信息、证书序列号、申请者公钥等明文信息,和签名密文。ca证书的具体使用流程如下:

  1. 服务方向ca机构提供公钥、组织信息、个人信息等,进行证书申请。
  2. ca机构通过线上或线下等多种手段验证申请中提供信息的真实性。
  3. 如果审核通过,ca签发证书给申请者。签名的生成方法是,用散列函数对明文信息进行计算,生成摘要,用ca的私钥对摘要进行加密生成最终的签名。
  4. 客户端向服务器发送请求,服务器将ca证书返回给客户端。
  5. 客户端会对证书进行验证。首先获取证书中的明文信息,然后用相同的散列函数进行计算,得到摘要内容;客户端会内置可信的ca信息,包括ca的公钥,客户端找到对应ca的公钥,将签名解密成摘要;最后将两份摘要进行对比,如果一致,则认为签名合法。客户端接着会验证证书的域名、有效期等信息。

可见,ca证书的合法性依然依赖非对称加密算法,也依赖ca证书的权威性。客户端内置的ca证书是ca的根证书,是ca的自签名证书,所以客户端只有根证书的公钥。如果服务器证书和ca根证书之间增加了一级证书机构,则需要增加一层验证,只要最终能够被任何信任的CA根证书验证合法即可。服务器证书->中间证书->根证书叫做证书链,一般服务器会提供证书链给客户端进行验证。证书链可以更好的管理证书。

tls/ssl握手过程


上图是我在本地抓的访问baidu的https报文,ssl握手过程如下:

1. client hello

https原理学习笔记_第2张图片
client hello是ssl握手中客户端发送的第一个包,全部明文传输,里面的内容包括:

  1. Version:支持的tls的最高版本,从低到高依次SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,当前基本不再使用低于TLSv1的版本。
  2. Random:客户端生成的随机数,用于后面对称加密通信密钥的生成。
  3. Session ID:复用连接,用于加快ssl握手的速度,后面再讲。
  4. Cipher Suites:客户端支持的加密套件列表,每一组套件包含对称加密算法、非对称加密算法和散列函数。
  5. Compression Methods:客户端支持的压缩算法列表,用于后续的信息压缩传输。
  6. Extension:扩展字段,包括请求的域名信息、支持协议与算法的相关参数以及其它辅助信息等。

2. server hello+Certificate+server done

a. server hello

https原理学习笔记_第3张图片
server hello是服务器返回的协商结果,主要内容有:

  1. Version:选择后续使用的tls协议版本。
  2. Random:服务的生成的随机数,也是用于后续通信密钥的生成。
  3. Session ID:服务端生成的会话id,服务端会储存这个信息,如果后续客户端携带这个会话id访问,可以减少握手步骤。
  4. Cipher Suites:服务端从客户端可选的加密套件中选择了一组,用作后续通信使用。
  5. Compression Methods:同上,服务端选择的压缩算法。

b. Certificate

https原理学习笔记_第4张图片
服务端把对应的证书链发送给客户端,第一个证书是服务器证书,第二个证书是中间证书。

c. server hello done

https原理学习笔记_第5张图片
server key exchange里面是服务器生成的DH算法需要使用的一些参数,如果采用rsa算法来协商密钥,则不需要这部分信息。server hello done标志着server hello的结束。

3. 证书校验

第三步,客户端需要验证证书是否合法,如不合法,给出相应的提示或者报错。验证内容主要包括以下几点:

  • 证书链的可信性,方法如前文所述。
  • 证书是否被吊销,如果使用者不合法,ca可以吊销证书;如果使用者的私钥丢失,使用者也可以申请吊销证书。服务器发送的Certificate里面一般会有提供CRL(证书吊销列表)的url地址:https原理学习笔记_第6张图片
    客户端可以从这个url下载crl,验证证书是否被吊销。有的服务器会提供OCSP(Online Certificate Status Protocol, 证书状态在线查询协议)的url,客户端可以通过这个url实时查询证书状态。
  • 验证证书有效期,证书的validity字段。
  • 验证证书域名是否和访问的域名一致。

4. client key exchange+change cipher spec+encrypted handshake message

https原理学习笔记_第7张图片

a. client key exchange

如果用dh算法来计算密钥的,这个字段里是客户端用dh算法生成的pre-master。如果采用rsa算法,这里是客户端生成的一个随机数pre-master,客户端用服务器公钥加密这个随机数,发送给服务端,服务端可以用私钥解密出这个随机数。至此客户端和服务端都获得了三个随机数,双方通过相同的算法计算出之后通信用的对称加密密钥。

b. change cipher spec

这是一个事件消息,客户端通知服务端后面就使用之前协商好的密钥和加密算法进行通信。

c. encrypted handshake message

客户端结合前面所有tls握手信息,用散列函数生成一份摘要,用协商好的密钥加密,发送给服务端进行验证。这是https通信中发出的第一个加密信息,如果服务端解密出来和自己生成的摘要一致,则说明密钥是一样的。

5. change cipher spec+encrypted handshake message

https原理学习笔记_第8张图片

a. change cipher spec

同样是个事件消息,服务端告诉客户端后面所有的通信都会用之前协商的方法进行加密。

b. encrypted handshake message

服务器也结合所有当前的通信参数信息生成一段数据,采用协商密钥加密并发送到客户端。客户端用同样的方法验证,验证通过则握手完成。

tips:

  1. 服务端可以在第二部的时候发送client_certificate_request信息,要求客户端发送自己的证书,从而进行双向验证,验证方法基本相同。
  2. server key exchange是可选项,不要用于发送一些补充信息,如不需要,可以不带。
  3. change cipher spec可以通知对端修改通信方式。
  4. 如果ssl握手失败或者ssl连接关闭,会发送alert信息,收到信息后,连接就回被断开。
  5. 密钥生成依赖于双方产生的随机数,如果是完全随机的,可以直接用pre-master来做密钥。但是我们用到的往往是伪随机,所以ssl协议要求用三个随机数来生成最终的密钥,让伪随机变得更加随机。

session复用

从上一章节可以看到不算上证书验证的时间,ssl握手需要2RTT,tcp握手才只需要1RTT,为了加快握手速度,并且减少握手过程中的性能损耗,tls协议提供了两种session复用或者说session缓存机制:session id/session ticket。

session id

session id是一个协议标准字段,由服务端支持,且几乎所有的服务器都支持。服务端会缓存之前握手成功的通信信息和对应的session id,nginx中1M内存约可以保存4000个session id机器相关信息,占用服务器资源较多。携带session id的ssl握手过程如下:

  1. 如果客户端和服务器之间曾经建立了连接,服务器会在握手成功后返回session ID,并保存对应的通信参数在服务器中;
  2. 如果客户端再次需要和该服务器建立连接,则在client_hello中session ID中携带记录的信息,发送给服务器;
  3. 服务器根据收到的session ID检索缓存记录,如果没有检索到或缓存过期,则按照正常的握手过程进行;
  4. 如果检索到对应的缓存记录,则返回change_cipher_spec与encrypted_handshake_message信息,两个信息作用类似,encrypted_handshake_message是当前的通信参数与密钥的hash值;
  5. 如果客户端能够验证通过服务器加密数据,则客户端同样发送change_cipher_spec与encrypted_handshake_message信息;
  6. 服务器验证数据通过,则握手建立成功,开始进行正常的加密数据通信。

session ticket

session ticket需要客户端和服务端都支持,是一个扩展字段,支持率比session id低很多。这种方式中,客户端会将之前的通信信息加密并缓存,密钥只有服务端知道,所以占用的服务器资源很少。如果session id和session ticket都支持,nginx会优先选择session ticket。携带session ticket的ssl握手过程如下:

  1. 如果客户端和服务器之间曾经建立了连接,服务器会在new_session_ticket数据中携带加密的session_ticket信息发送给客户端,由客户端保存;
  2. 如果客户端再次需要和该服务器建立连接,则在client_hello中扩展字段session_ticket中携带加密信息,一起发送给服务器;
  3. 服务器解密sesssion_ticket数据,如果解密失败,则按照完整的握手过程进行;
  4. 如果解密成功,则返回change_cipher_spec与encrypted_handshake_message信息,两个信息作用与session ID中类似;
  5. 如果客户端能够验证通过服务器加密数据,则客户端同样发送change_cipher_spec与encrypted_handshake_message信息;
  6. 服务器验证数据通过,则握手建立成功,开始进行正常的加密数据通信。

对比

  1. session id和session ticket的区别有点像http中的session和cookie,缓存位置不一样。
  2. session ticket占用服务器资源更少。
  3. session id是标准协议字段,如果之前没有建立过连接,则client hello中该值为空;如果客户端不支持session ticket,则client hello的扩展字段中不存在session ticket,如果存在,就支持。
  4. 二者的握手延时都是1*RTT,因为最后一次握手之后,客户端不需要等待服务端的确认,可以直接发送数据。

https性能与优化

https性能损耗

  1. 握手延时。即使是session复用,也比http多1*RTT。
  2. 占用较多的cpu资源。https通信主要用到对称加解密和非对称加解密,rsa解密速度慢是所有人都知道的瓶颈,如果qps比较大的话,会非常的消耗cpu资源。

https性能优化

  1. cdn接入。cdn边缘节点离用户近,可以缓解https延时大的问题。cdn/动态加速/负载均衡具备的缓存静态资源、长连接、连接复用、智能选路、ssl卸载等功能都可以极大的优化https延时,几乎已经成为https接入的必选项。
  2. session复用。session复用的好处不仅可以体现在优化延时上,基于session缓存建立的https连接不需要服务器使用RSA私钥解密获取Pre-master信息,可以省去不少的cpu的消耗。
  3. 硬件加速。使用ssl专用的网卡,可以更好的释放cpu资源。
  4. 使用http2。http2的一些优化可以提高整个通信的性能,以后有时间再学习下http2。

你可能感兴趣的:(https,学习,ssl,阿里云)