主要摘抄自:SSL/TLS 协议运行机制的概述
1. 概述
1.1 基本概念
1.1.1 SSL (Secure Socket Layer,安全套接字层)
SSL 为 Netscape 所研发,用以保障在 Internet 上数据传输之安全,利用数据加密 (Encryption) 技术,可确保数据在网络上之传输过程中不会被截取,当前为3.0版本。
SSL 协议可分为两层: SSL 记录协议(SSL Record Protocol):它建立在可靠的传输协议(如 TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
1.1.2 TLS (Transport Layer Security,传输层安全协议)
用于两个应用程序之间提供保密性和数据完整性。
TLS 1.0 是 IETF(Internet Engineering Task Force,Internet 工程任务组)制定的一种新的协议,它建立在 SSL 3.0 协议规范之上,是 SSL 3.0 的后续版本,可以理解为 SSL 3.1,它是写入了 RFC 的。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。
1.2 作用
不使用 SSL/TLS 的 HTTP 通信,就是不加密的通信。所有信息明文传播,带来了三大风险。
(1) 窃听风险(eavesdropping):第三方可以获知通信内容。
(2) 篡改风险(tampering):第三方可以修改通信内容。
(3) 冒充风险(pretending):第三方可以冒充他人身份参与通信。
SSL/TLS 协议是为了解决这三大风险而设计的,希望达到:
(1) 所有信息都是加密传播,第三方无法窃听。
(2) 具有校验机制,一旦被篡改,通信双方会立刻发现。
(3) 配备身份证书,防止身份被冒充。
2. 运行过程
2.1 简述
客户端先向服务器索取公钥,通过该公钥将客户端生成的一个随机数来加密并传输到服务端(此时涉及到的是非对称加密)。
然后客户端、服务端双方基于前面说的那个随机数(实际上总共涉及到三个随机数,这里的这个是最关键的),以及约定好的算法,在两端各自生成 “对话密钥”(session key),注意,虽然是各自生成的,但是因为使用了同样的算法以及随机数,因此两端生成的 session key 是一致的。之后,就可以通过 session key 来将双方通信的数据进行加解密。(这里涉及到的是对称加密)。
这里总共涉及到了两类加密算法:
(1)非对称加密是为了安全的传输用于生成 session key 的随机数,防止被攻击者破解;
(2)而对称加密因为 session key 只有通信双方知道,因此基于对称加密可以减少加解密的时间,提高通信效率。
因此 SSL/TLS 协议的基本过程是这样的:
(1) 客户端向服务器端索要并验证公钥。
(2) 双方协商生成"对话密钥"。
(3) 双方采用"对话密钥"进行加密通信。
上面过程的前两步,又称为 “握手阶段”(handshake)。
2.2 握手阶段
2.2.1 客户端发出请求(ClientHello)
客户端(通常是浏览器)先向服务器发出加密通信的请求,这被叫做 ClientHello 请求。
客户端主要向服务器提供以下信息:
(1) 支持的协议版本,比如 TLS 1.0 版。
(2) 一个客户端生成的随机数,稍后用于生成 “对话密钥”。
(3) 支持的加密方法,比如 RSA 公钥加密。
(4) 支持的压缩方法。
注意,这里涉及到了第一个随机数。
2.2.2 服务器回应(ServerHello)
服务器收到客户端请求后,向客户端发出回应,这叫做 ServerHello。服务器的回应包含以下内容:
(1) 确认使用的加密通信协议版本,比如 TLS 1.0 版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
(2) 一个服务器生成的随机数,稍后用于生成 “对话密钥”。
(3) 确认使用的加密方法,比如 RSA 公钥加密。
(4) 服务器证书。
除了上面这些信息,如果服务器需要确认客户端的身份,就会再包含一项请求,要求客户端提供"客户端证书"。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供 USB 密钥,里面就包含了一张客户端证书。
注意,这里涉及到了第二个随机数。
2.2.3 客户端回应
客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。
如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息。
(1) 一个随机数(pre-master key)。该随机数用服务器公钥加密,防止被窃听。
(2) 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
(3) 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容(这里说的所有内容,个人推测应该也包括 ClientHello 时客户端生成的随机数等)的 hash 值(应该就是数字签名),用来供服务器校验(应该是用来防止最开始说的篡改风险)。
这里涉及到了第三个随机数,也是最关键的那个。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把 “会话密钥”。
此外,如果前一步,服务器要求客户端证书,客户端会在这一步发送证书及相关信息。
2.2.4 服务器的最后回应
服务器收到客户端的第三个随机数 pre-master key 之后,计算生成本次会话所用的 “会话密钥”。然后,向客户端最后发送下面信息。
(1)编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的 hash 值,用来供客户端校验。(同理)
至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用 “会话密钥” 加密内容。
3. 补充
3.1 非对称加密时的私钥和公钥
在非对称加密阶段,私钥和公钥只使用了一次,其中公钥用于客户端加密第三个随机数 pre-master key,私钥用于服务端解密获取客户端传输过来的 pre-master key。
3.2 关于三个随机数
"不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。
对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。
pre master 的存在在于 SSL 协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么 pre master secret 就有可能被猜出来,那么仅适用 pre master secret 作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上 pre master secret 三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。"
3.3 客户端是怎么验证服务端的证书的
前提:客户端会预置有效的根证书。
有效的证书需要由权威机构 CA(数字证书管理机构) 签名,CA 会用自己的私钥来生成数字签名。这个权威机构CA 客户端是可以完全信任的,客户端浏览器会安装 CA 的根证书,由 CA 签名的证书是被 CA 所信任的,这就构成了信任链,所以客户端可以信任该服务器的证书。
客户端与服务器建立 SSL 连接时,服务器将自身的证书传输给客户端,客户端在验证证书的时候,先看 CA 的根证书是否在自己的信任根证书列表中。再用 CA 的根证书提供的公钥来验证服务器证书中的数字签名,如果公钥可以解开签名,证明该证书确实被 CA 所信任。再看证书是否过期,访问的网站域名与证书绑定的域名是否一致。这些都通过,说明证书可以信任。
接下来使用服务器证书里面的公钥进行服务器身份的验证。 客户端生成一个随机数给到服务器。 服务器使用私钥对随机数进行签名,并回传给到客户端。 客户端用服务器证书的公钥(因为上一步已经验证了证书是可信的,则证书中的公钥是有效的)对随机数的签名进行验证,若验证通过,则说明对应的服务器确实拥有对应服务器证书的私钥,因此 判断服务器的身份正常(因为私钥负责签名,公钥负责验证)。否则,表明服务器身份被伪造。这些都没问题才说明服务器是可信的。
3.4 是如何防止篡改风险的(暂时的推测)
关于防止被篡改,应该分为握手阶段与正式的数据通信阶段。
在握手阶段呢,客户端传输给服务端的数据,以及服务端传输给客户端的数据,都需要防止被篡改。
下面的内容暂时为本人的推测,还没有找到确定的资料进行验证。
握手阶段:
(1)客户端传输给服务端的数据,是在客户端回应的时候(见 2.2.3 )时(注意数字签名的时机)才会将数字签名一起将之前传输的所有内容进行数字签名并发送给服务端,此时客户端已经可以具备关键的 pre-master key,因此可以在本端生成 “会话密钥”,这个密钥是对除服务端外进行保密的,因此 猜测 此时客户端应该利用 “会话密钥” 对之前的内容进行数字签名(注意,数据加密是使用公钥),然后服务端接收到内容后,会使用私钥进行解密,这里应该就是关键了,即如果服务端接收到的数据被篡改了,那么解密出来的 pre-master key 肯定是有问题的,拿着这个有问题的 pre-master key 得出的 “会话密钥” 也是有问题的,然后拿着有问题的 “会话密钥” 对数字签名进行验证,则是验证无效的。(基于签名与验证都是同一 “钥匙”)
(2)服务端传输给客户端的数据,则是利用只有服务端自身知道的私钥来进行数字签名,然后客户端使用公钥来验证签名。
数据通信阶段:
而正式通信时的数据,有两种可能,双方都是用只有自己与对方知道的 “会话密钥” 进行数字签名以及验证。
或者客户端传输给服务端时,使用前面说的,而服务端传输给客户端时,服务端使用私钥签名,客户端使用公钥验证。
而至于通信时防止被冒充,应该也是基于数字签名的,通过数字签名的验证,确认数据没有被篡改,则对方没有被冒充。
3.5 一个脑洞
在总结的时候,突然想着,假设攻击者一开始就伪装成客户端,跟服务端建立起来了 HTTPS 通信。
想到这里,细想起来,发现其实这种想法有点多余。
首先,前面提过服务端也可以要求客户端提供被授权的密钥(就要某些金融机构的 U 盾),用来验证客户端的身份。
其次,就要没有要求客户端提供身份验证,此时攻击者伪装成了客户端跟服务端建立起了 HTTP 通信,有了 “会话密钥”,但是这个密钥是一次性的,而且正常的客户端跟服务端通信的时候,涉及到重要内容,肯定是基于账号密码的,攻击者即使与服务端建立了 HTTPS 通信,但是不知道有效的账号密码,也就无法进一步获取敏感数据。而如果攻击者知道某个用户的账户密码,此时也不关 HTTPS 通信什么事了,因为本身就被黑了。
HTTPS 的目的是为了防止通信时数据被窃听、篡改,以及正在通信时的双方被冒充,注意,这里说的是通信进行时防止被冒充。
参考文章
1、SSL/TLS 协议运行机制的概述
2、图解 SSL/TLS 协议
3、https://www.cnblogs.com/changbaishan/p/7676615.html
4、详解https是如何确保安全的?
5、为什么HTTPS比HTTP更安全?