HTTPS 原理详解

HTTP 协议是使用明文进行数据传输的,这感觉就像是在互联网上裸奔一样,只要能够截获请求,就可以窃听你传输的信息,并还可以进行篡改数据,甚至冒充用户进行通信

所以,为了保证数据传输的安全性,就需要对传输的数据进行加密,这样的话即便数据被其他人截获了,也拿不到真正请求的数据信息

HTTPS 就是在 HTTP 的基础之上,添加了数据加密传输的功能,而 HTTPS 使用的协议就是 TLS/SSL

TLS 和 SSL

TLS是传输层安全的缩写,SSL 是安全套接字层的安全,都是加密数据和 internet上确保数据安全传输的协议

  1. 那它们有什么区别呢

    SSL 是 Netscape 公司提出的安全保密协议,在浏览器和服务器之间构造安全通道来进行数据传输,它是运行在 TCP/IP层之上,在应用层之下的协议

    1994年,Netscaoe公司设计了SSL协议(Secure Sockets Layer),之后又对该版本进行了升级;

    1996年,SSL3.0版本问世,并且得到了广泛的应用

    TLS是后面互联网标准化组织ISOC接替了Netscape公司,在 1999 年分布了SSL的升级版本TLS1.0版本

    之后,在2006年和2008年,TLS进行了两次升级,分别为TLS 1.1版和TLS 1.2版。最新的变动是2011年TLS 1.2的修订版。

    目前,应用最广泛的是TLS 1.0,接下来是SSL 3.0。但是,主流浏览器都已经实现了TLS 1.2的支持。

    TLS 1.0通常被标识为SSL 3.1,TLS 1.1为SSL 3.2,TLS 1.2为SSL 3.3。

  2. 基本运行过程

    TLS/SSL 协议的基本思想就是使用公钥加密法,首先客户端向服务器索要公钥,获取到公钥之后,然后加密数据进行传输;服务端收到客户端传来的加密数据之后,使用私钥对数据进行解密

    那如何保证公钥不被篡改呢?
解决办法:将公钥放到数字证书当中,只要数字证书是安全的,那么公钥就是安全的
使用公钥加密的计算量很大,如何这个过程中耗用的时间呢
解决办法:客户端和服务器的每一次对话,都会产生一个"session key",也就是对话密钥,使用该密钥对数据进行对称加密,而公钥只用于加密对话密钥,因为对称加密的计算速度很快,所以整个加密过程的耗时就会减少

使用 TSL/SSL 通信的整个过程如下所示:

  1. 客户端向服务器索要公钥
  2. 双方协商"对话密钥"
  3. 双方采用”对话密钥”对数据进行加密

其中 1,2 步骤又称之为"握手阶段"

握手阶段的详细过程

"握手阶段"涉及四次通信,需要注意的是,"握手阶段"的所有通信都是明文的。

  1. 客户端发出加密通信的请求,向服务器提供如下的信息

    (1) 支持的协议版本,比如TLS 1.0版。
    
    (2) 一个客户端生成的随机数,稍后用于生成"对话密钥"。
    
    (3) 支持的加密方法,比如RSA公钥加密。
    
    (4) 支持的压缩方法。
    
    1. 服务接收到客户端的请求之后,向客户端响应
    (1) 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
    
    (2) 一个服务器生成的随机数,稍后用于生成"对话密钥"。
    
    (3) 确认使用的加密方法,比如RSA公钥加密。
    
    (4) 服务器证书。
    

    当然,一些金融机构还会要求服务器确认客户端的身份,要求客户端提供"客户端证书",因为金融机构往往只允许认证客户连入自己的网络,所以就会向客户提供 USB密钥,在这个 USB密钥就包含了"客户端证书";这就是常用的U盾

  2. 客户端收到证书之后,首先就会验证服务器的证书是不是由可信的机构颁发的,以及证书是否已经过期,或证书中的域名是否与实际的域名是一样的,如果证书有问题,就会向客户端发出警告,由客户端选择是否还需要继续通信
    如果证书没有问题,客户端就从证书中取出公钥,然后向服务器发送以下信息:

(1) 一个随机数。该随机数用服务器公钥加密,防止被窃听。

(2) 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。

(3) 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。

上面第一项的随机数,是整个握手阶段出现的第三个随机数,又称"pre-master key"。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把"会话密钥"。

那为什么需要用三个随机数来生成通信的密钥呢?

"不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。

对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。

pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅适用pre master secret作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。"

当然,如果服务器还需要客户端的证书,客户端还会在这一步发送证书相关的信息

4 服务器收到客户端的响应之后,计算生成本次会话所用的"会话密钥"。然后,向客户端发送如下的信息:

(1)编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。

(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。

至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用"会话密钥"加密内容。

  1. session 恢复

在握手阶段,如果处于某种原因,对话中断了,那么就需要重新握手,这不仅耗时而且浪费带宽;所以,有没有方法能够重新之前的会话呢?

现在有两种方法来恢复之前的会话,第一种就是使用 sessionID,第二种就是使用sessionKey

SessionID

sessionID 就是说每次对话都有一个编号(sessionID)。如果连接中断了,那么在下次重连时,只需要客户端向服务端提供了这个sessionID,并且服务端有这个编号的记录,这样双方就可以重新使用之前的对话密钥,而不需要重新生成一把了

SessionKey

服务器生成一个sessionTiket,这个sessionTicket 是加密的,里面包含本次对话的信息,包括对话密钥加密方法等,这个sessionTicket只有服务器能够解密。

在握手阶段,服务器将这个sessionTicket发送给客户端,当出现断链的时候,客户端将这个sessionTicket发送给服务端,服务器收到这个sessionTicket以后,如果能够成功解密,那么就不需要再重新握手了

使用sessionTicket就能够很好的解决sessionID中由于集群问题带来的不同服务器中数据不一致的问题了

参考链接:

https://www.ruanyifeng.com/blog/2014/02/ssl_tls.html

https://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html

你可能感兴趣的:(HTTPS 原理详解)