一 点睛
握手协议是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记录协议进行密码通信。
从结果来看,握手协议完成了下列操作。
客户端获得服务器合法公钥,完成了服务器认证。
服务器获得了客户端合法公钥,完成了客户端认证(当需要客户端认证时)
客户端和服务器生成了密码通信中使用的共享密钥
客户端和服务器生成了消息认证码中使用的共享密钥。
版权声明:本文为CSDN博主「chengqiuming」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chengqiuming/article/details/83115642