TLS握手协议详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengqiuming/article/details/83115642

一 点睛

握手协议是TLS握手协议的一部分,负载生成共享密钥以及交换证书。其中,生成共享密钥是为了进行密码通信,交换证书是为了通信双方相互进行认证。

握手协议这一名称中的“握手”,是服务器和客户端在密码通信之间交换一些必要信息这一过程比喻。

由于握手协议的信息交换是在没有加密的情况下进行的(即使用“不加密”这一密码套件),也就是说,在这一协议中所收发的所有数据都可能被窃听者窃听,因此在这一过程中必须使用公钥密码或DH密钥交换。

二 TLS握手协议过程图

三 过程

1 ClientHello(客户端->服务器)

客户端向服务器发送ClientHello消息

客户端:你好,我能理解的密码套件有RSA/3DES,或者DSS/AES,请问我们使用哪一种密码套件进行通信呢?

简单的说,客户端会向服务器发送下来消息。

  • 可用的版本号

  • 当前时间

  • 客户端随机数

  • 会话ID

  • 可用的密码套件清单

  • 可用的压缩方式清单

为什么要发送“可用的版本号”“可用的密码套件清单”和“可用的压缩方式清单”呢?因为不同的客户端(Web浏览器)所支持的方式不同,具体使用哪一种方式来通信,需要和服务器进行协商。

“当前时间”在基本的TLS中是不使用的,但上层协议中有可能会使用这一信息。“客户端随机数”是一个客户端生成的不可预测的随机数。在后面的步骤中会使用到它。

“会话ID”是当客户端和服务器希望使用之前建立的会话(通信路径)时所使用的信息。

2 ServerHello(客户端<-服务器)

对于客户端发送的ClientHello消息,服务器会返回一个ServerHello消息。

服务器:你好,我们就用RSA/3DES来进行通信吧。

服务器会将下列信息随ServerHello消息一起发出去。

  • 使用的版本号

  • 当前时间

  • 服务器随机数

  • 会话ID

  • 使用的密码套件

  • 使用的压缩方式

服务器根据客户端在ClientHello消息中发送过来的信息确定通信中使用的“版本号”“密码套件”和“压缩方式”。

“当前时间”在基本的TLS中是不使用的,但上层协议中可能会使用这一信息。

“服务器随机数”是一个由服务器生成的不可预测的随机数。这个随机数必须与客户端生成的随机数无关,在后面的步骤中会使用到它。

3 Certificate(客户端<-服务器)

服务器发送Certificate消息。

服务器:好,这是我的证书。

通过Certificate消息,服务器会向客户端发送下列信息。

  • 证书清单

证书清单是一组X.509v3证书序列,首先发送的是服务器(发送方)的证书,然后会按顺序发送对服务器证书的认证机构的证书。

客户端会对服务器发过来的证书进行验证。当以匿名方式通信时,不发送Certificate消息。

4 ServerKeyExchange(客户端<-服务器)

服务器发送ServerKeyExchange消息。

服务器:我们用这些信息来进行密钥交换吧。

当Certificate消息不足以满足需求时候,服务器会通过ServerKeyExchange消息向客户端发送一些必要信息。具体发送的信息内容会根据所使用的密码套件而有所不同。

当不需要这些信息时候,将不会发送ServerKeyExchange消息。

5 CertificateRequest(客户端<-服务器)

服务器发送CertificateRequest消息

服务器:对了,请给我看一下你的证书吧。

CertificateRequest消息用于服务器向客户端请求证书,这是为了进行客户端认证。通过这一消息,服务器会向客户端发送下列信息。

  • 服务器能够理解的证书类型清单

  • 服务器能够理解的认证机构名称清单

当不使用客户端认证时,不会发送CertificateRequest消息。

6 ServerHelloDone(客户端<-服务器)

服务器发送ServerHelloDone消息。

服务器:问候到此结束。

这一消息表示从ServerHello消息开始的一系列消息的结束。

7 Certificate(客户端->服务器)

客户端发送Certificate消息。

客户端:这是我的证书。

当步骤5中服务器发送CertificateRequest消息时,客户端会将自己的证书同Certificate消息一起发送给服务器。

服务器读取客户端的证书并进行验证。

当服务器没有发送CertifacateRequest消息时,客户端不会发送Certificate消息。

8 ClientKeyExchange(客户端->服务器)

客户端发送ClientKeyExchange消息。

客户端:这是经过加密的预备主密钥。

当密码套件中包含RSA时,会随着ClientKeyExchange消息一起发送经过加密的预备主密码。

当密码套件中包含DH密钥交换时,会随着ClientKeyExchange消息一起发送ClientKeyExchange的公开值。

预备主密码是由客户端生成的随机数,之后会被用作生成主密码的种子。

根据预备主密码,服务器和客户端都计算出相同的主密码,然后再根据主密码生成下列比特序列(密码素材)。

  • 对称密码的密钥
  • 消息认证码的密钥
  • 对称密码的CBC模式中使用的初始化向量(IV)

9 CertificateVerify(客户端->服务器)

客户端发送CertificateVerify消息

客户端:我确实是客户端证书的持有者本人。

客户端只有在服务器发送CertificateRequest消息时候才会发送CertificateVerify消息。这个消息的目的是向服务器证明自己的确持有客户端证书的私钥。

为了实现这一目的,客户端会计算“主密码”和“握手协议中传输的消息”的散列值,并加上自己的数字签名后发送给服务器。

10 ChangeCipherSpec(客户端->服务器)

客户端发送ChangeCipherSpec消息。

客户端:好,现在我要切换密码了。

实际上,ChangeCipherSpec消息并不是握手协议的消息,而是密码规格变更协议消息。

在ChangeCipherSpec消息之前,客户端和服务器之间已经交换了所有关于密码套件的信息,因此在收到这一消息时候,客户端和服务器会同时切换密码。

在这个消息之后,TLS记录协议就开始使用双方协商决定的密码通信方式了。

11 Finished(客户端->服务器)

客户端发送Finished消息

客户端:握手协议到此结束。

由于已经完成了密码切换,因此Finished消息是使用切换的密码套件发送。实际负责加密操作的是TLS记录协议。

Finished消息的内容是固定的,因此服务器可以将接收的密文解密,来确认所收到的Finished消息是否正确。通过这一消息,就可以确认握手协议是否正常结束,密码套件的切换是否正确。

12 ChangeCipherSpec(客户端<-服务器)

这次轮到服务器发送ChangeCipherSpec消息了

服务器:好,现在我要切换密码了。

13 Finished(客户端<-服务器)

和客户端一样,服务器也会发送Finished消息。

服务器:握手协议到此结束

这一消息会使用切换后的密码套件来发送。实际服务加密操作的是TLS记录协议。

14 切换至应用数据协议

在此之后,客户端和服务器会使用应用数据协议和TLS记录协议进行密码通信。

从结果来看,握手协议完成了下列操作。

  • 客户端获得服务器合法公钥,完成了服务器认证。
  • 服务器获得了客户端合法公钥,完成了客户端认证(当需要客户端认证时)
  • 客户端和服务器生成了密码通信中使用的共享密钥
  • 客户端和服务器生成了消息认证码中使用的共享密钥。

猜你喜欢

转载自blog.csdn.net/chengqiuming/article/details/83115642