TLS/SSL 协议交互流程_ssl交互过程
1.SSL 简介
SSL(Secure Socket Layer)安全套接层是Netscape公司率先采用的网络安全协议。它是在传输通信协议(TCP/IP)上实现的一种安全协议,采用公开密钥技术。SSL广泛支持各种类型的网络,同时提供三种基本的安全服务,它们都使用公开密钥技术。
1.1 安全服务
- 信息保密,通过使用公开密钥和对称密钥技术以达到信息保密。
- 信息完整性,确保SSL业务全部达到目的。
- 双向认证,客户机和服务器相互识别的过程。
- SSL的安全性服务对终端用户来讲做到尽可能透明。
2. 通信流程
- 报文信息:
- 交互流程
2.1 三次握手
TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手进行的。整个过程的示意图如下:
三次握手在客户端调用connect()和服务器accept()之间完成
2.2 客户端 -> 服务端:Client Hello
客户端发送Client Hello Message,表明自己可以使用的SSL版本、以及相应参数。
- client_version:SSL版本。客户端会从高到低去尝试填入自己支持的SSL版本。
- random:客户端随机数。客户端的随机字符序列,用于后续协商密钥。
- session_id:本次会话ID。用于后面恢复会话。如果没有会话ID,则这里可以为空。
- cipher_suites:支持的加密套件列表。根据客户端想要使用的且自己支持的加密套件由高到低排序。
- compression_methods:压缩算法列表。根据客户端想要使用的且自己支持的压缩算法由高到低排序,可以为null,表示不要压缩。
从上图可以看到:
- 握手协议消息类型为Client Hello
- 客户端支持的TLS版本为TLS 1.2 (0x0303), 其中0x0303为内部版本号,如TLS1.3为0x0304
- 客户端生成的32字节随机数
- 客户端支持的加密套件,优先级从上到下
2.3 服务端 -> 客户端:Server Hello
服务器接受到ClientHello后,会返回ServerHello。服务器从客户端在ClientHello中提供的密码套件、SSL/TLS版本、压缩算法列表里选择它所支持的项,并把它的选择包含在ServerHello中告知客户端,ServerHello中同样会包含一个随机数,同样4+28 字节类型,由服务器生成。
- server_version:服务器支持的SSL版本。
- random:服务器随机数。服务器端的随机字符序列,用于后续协商密钥。
- session_id:本次会话ID。如果服务器找到了客户端传过来的session_id会话,并且可以恢复会话,那么这里会填入和ClientHello相同的session_id;否则这里将填入新session_id
- cipher_suite:密钥套件。服务器支持的,且是从客户端给的列表中选的密钥套件。
- compression_method:压缩算法。服务器支持的,且是从客户端给的列表中选的压缩算法。
接下来SSL协议的建立就基于服务器选择的密码套件类型、SSL/TLS协议版本以及压缩算法。
从上图可以看到:
- 握手协议消息类型为Server Hello
- 服务端确定的TLS版本为TLS 1.2
- 服务端生成的32字节随机数
- 服务端确定的加密套件:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,该加密套件各字段用途如下
2.4 服务端 -> 客户端:Certificate, Server Key Exchange, Server Hello Done
- 【Certificate*】服务器证书
和所选密钥套件中密钥交换算法(Key Exchange)匹配的,用于客户端验证服务器身份和交换密钥的X.509证书。
- 【Server Key Exchange*】服务器密钥交换信息
如果服务器没有证书,或者服务器的证书仅用来签名(如DSS证书、签名RSA证书),或者使用的是FORTEZZA KEA密钥交换算法(现在已经不用了,不需要去了解),那么就需要发送这条消息。
- 【Certificate Request *】证书请求
要求客户端也发送它的证书,让服务端校验客户端的身份。
- 【Server Hello Done】服务器Hello阶段结束信息
一条简单的表明状态的空消息。
从上图可以了解到,本次通信tcp包携带了3个tls握手协议包:
-
Certificate消息:Server Key Exchange消息:
1.1 服务端证书,id-at-commonName=*.pku.edu.cn\"表示为北京大学服务器网站
1.2 证书链,该证书链包含根证书id-at-commonName=DigiCert Global Root CA, 该根CA为知名签发机构(隶属于美国) -
Server Key Exchange消息:
2.1 服务端DH参数,参与生成主密钥
2.2 服务端签名,用于验证消息有效性 -
Server Hello Done消息:通知客户端加密套件协商结束
2.5 客户端 -> 服务端:Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
【校验服务器身份】
客户端会校验服务器发过来的证书的合法性,包括:
- 证书链的可信性
- 证书是否被吊销
- 证书是否处于有效期
- 证书的域名是否和当前访问域名匹配
如果发现证书不合法,客户端可以发起告警信息。
从上图可以了解到,本次通信tcp包携带了3个tls握手协议包:
-
Client Key Exchange消息Change Cipher Spec消息:通知服务端,客户端已准备好进行密文通信Change
Cipher Spec消息:通知服务端,客户端已准备好进行密文通信1.1 客户端DH参数,参与生成主密钥
-
Change Cipher Spec消息:通知服务端,客户端已准备好进行密文通信
-
Encrypted Handshake Message消息:同Finished消息(密文形式)
2.6 服务端 -> 客户端: New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
- 【Certificate*】客户端证书
如果服务器发送了“Certificate Request”,要求校验客户端身份,那么客户端需要回应自己的证书。如果客户端没有合适的证书,直接抛出告警信息让服务端处理(服务端的处理方式通常就是断开TCP连接)。和所选密钥套件中密钥交换算法(Key Exchange)匹配的,用于服务器验证客户端身份的X.509证书。
- 【Client Key Exchange*】客户端密钥交换信息
合法性校验通过后,客户端计算产生随机数字Pre-master,并用证书公钥加密,发送给服务器。
对于不同的密钥交换算法,密钥交换信息格式也不同:
- 【Certificate Verify*】客户端证书校验信息
用于提供客户端证书的显示校验信息,仅在具有签名功能的客户端证书(也就是除包含固定diffie-hellman参数的证书外的所有证书)之后发送。它是采用客户端的私钥加密的一段基于已经协商的通信信息得到的数据,服务器可以用公钥解密验证。
- 【Change Cipher Spec】更换加密规约
此时客户端已经获得全部的计算协商密钥所需信息:两个明文随机数random_S与random_C,还有自己计算产生的Pre-master。
用于提示服务端这条连接以后都使用当前协商好的加密方式以及主密钥,是一条事件消息。
- 【Finish(Encrypted Handshake Message)】完成信息
当所有操作完成后,发送Finish信息。Finish信息包含了Handshake信息、主密钥的哈希散列(如SHA、MD5)数据,用于验证身份校验和密钥交换过程都成功了。Finish消息不要求收到回包,发送之后可以立刻进行加密应用数据传输。
从上图可以了解到,本次通信tcp包携带了3个tls协议包:
- New Session Ticket消息: 服务器在TLS握手过程中生成一个新的会话票据(Session Ticket),并将其发送给客户端。客户端可以在后续的TLS握手中使用该会话票据来恢复之前的会话状态,从而避免了重新进行完整的TLS握手流程,提高了握手的效率和安全性。
- Change Cipher Spec消息:通知客户端,服务端已准备好进行密文通信
- Encrypted Handshake Message消息:同Finished消息(密文形式)
2.7 客户端 服务端:Application Data
从上图可以看到:
- 该消息不属于TLS握手协议,属于Application Data Protocol,是TLS协议的另一个子协议。
- Encrypted Application Data: 所有应用数据都被加密传输。
2.8 总结
客户端三次握手后多次调用SSL_connect 接口实现客户端和服务端的密钥交换等逻辑,直到 SSL_connect 返回 1时候结束
参考:
https://www.cnblogs.com/sunfie/p/18651937
https://blog.csdn.net/chasonli666/article/details/89278600