文章目录
SSL协议原理
SSL(Security Socket Layer)是一个安全协议,为基于TCP的应用层协议提供安全连接,SSL介于TCP/IP协议栈第四层和第七层之间。SSL可以为HTTP协议提供安全例案件。SSL为网络上数据的传输提供安全性保障。
SSL协议结构
SSL协议结构分为两层:
-
底层为SSL记录协议(SSL record protocol)
- 主要负责对上层数据进行分块、压缩、计算并添加MAC(Message Authenticate Code ,散列算法计算消息认证代码)、加密,最后把记录块传输给对方
-
上层:SSL握手协议(SSLhandshake protocol)、SSL密码变化协议(SSL change cipher spec protocol)、SSL警告协议(SSL alert protocol)
- SSL握手协议:客户端和服务器通过握手协议建立一个会话。会话包含一组参数,主要有会话ID、对方的证书、加密算法列表(包括密钥交换算法、数据加密算法和MAC算法)、压缩算法以及主密钥。SSL会话可以被多个连接共享,以减少会话协商开销。
- SSL密码变化协议:客户端和服务器端通过密码变化协议通知接收方,随后的报文都将使用新协商的加密算法列表和密钥进行保护和传输。
- SSL警告协议:用来允许一方向另一方报告告警信息。消息中包含告警的严重级别和描述。
SSL原理(握手协议)
通过SSL握手协议协商数据传输中要用到的相关安全参数,并对对端的身份进行验证。
SSL握手协议第一阶段
客户端发送一个ClientHello消息,包含参数:
- 版本:消息中协议版本是两个byte长度分别表示主次版本。目前SSL拥有的版本有SSLv1、SSLv2、 SSLv3以及TSLv1 (即SSLv3.1 )。
- 随机数: 32位时间戳+28字节随机序列,用于在后面计算所有消息的摘要或计算主密钥。
- 会话ID: SSL会 话ID标识一次会话用,可以重用。
- 客户端支持的密码算法列表( CipherSuite) :密钥套件列表,列表中包含了Client端支持的所有密钥套件。
- 客户端支持的压缩方法列表:客户端支持的压缩算法列表,填0表示空。
当服务器收到包含以上信息的ClientHello消息后,服务器发送ServerHello消息,包括参数:
- 版本:服务器拿出ClientHello消息中的版本号,再看看自己支持的版本列表,选择两者都支持的最高版本号定为这次协商出来的SSL协议使用的版本。
- 服务器产生的随机数:此处产生的随机数与ClientHello消息中的类似。
- 会话ID:服务器端检测到传过来的Session ID 是空或者检索Session列表没有发现传过来的Session ID就会新建一个。
服务器从客户端建议的密码算法中挑出一套(CipherSuite)密码算法
服务器从客户端建议的压缩方法中挑出一个压缩算法
客户端Client Hello数据包
服务端server Hello数据包
SSL握手协议第二阶段
Certificate消息( 可选)
一般情况下,除了会话恢复时不需要发送该消息,在SSL握手的全流程中,都需要包含该消息。消息包含一个X.509证书,证书中包含公钥,发给客户端用来验证签名或在密钥交换的时候给消息加密。
服务端将自己的证书下发给客户端,让客户端验证自己的身份,客户端验证通过后取出证书中的公钥。
Server Key Exchange (可选)
根据之前在ClientHello消息中包含的CipherSuite信息,决定了密钥交换方式(例如RSA或者DH),因此在Server Key Exchange消 息中便会包含完成密钥交换所需的一系列参数。
Certificate Request (可选)
服务器端发出CertificateRequest消息,要求客户端发他自己的证书过来进行验证。该消息中包含服务器端支持的证书类型(RSA、DSA、ECDSA等)和服务器端所信任的所有证书发行机构的CA列表,客户端会用这些信息来筛选证书。
ServerHello Done
该消息表示服务器已经将所有信息发送完毕,接下来等待客户端的消息。
Certificate消息数据包
Server Key Exchange消息数据包
在Diffie-Hellman中,客户端无法自行计算预主密钥; 双方都有助于计算它,因此客户端需要从服务器获取Diffie-Hellman公钥。
由上图可知,此时密钥交换也由签名保护。
ServerHello Done数据包
SSL握手协议第三阶段
Certificate ( 可选)
如果在第二阶段服务器端要求发送客户端证书,客户端便会在该阶段将自己的证书发送过去。服务器端在之前发送的Certificate Request消息中包含了服务器端所支持的证书类型和CA列表,因此客户端会在自己的证书中选择满足这两个条件的第一个证书发送过去。若客户端没有证书,则发送一个no_ certificate警告 。
Client Key exchange
根据之前从服务器端收到的随机数,按照不同的密钥交换算法,算出一一个pre-master,发送给服务器,服务器端收到pre-master算出main master.而客户端当然也能自己通过pre-master算出main master.如此以来双方就算出了对称密钥。
Certificate verify (可选)
只有在客户端发送了自己证书到服务器端,这个消息才需要发送。其中包含一个签名,对从第一条消息以来的所有握手消息的HMAC值(用master_ secret) 进行签名。
Client Key exchange数据包
SSL握手协议第四阶段
建立起一个安全的连接,客户端发送一个Change Cipher Spec消息,并且把协商得到的CipherSuite拷贝到当前连接的状态之中。然后,客户端用新的算法、密钥参数发送一个Finished消息,这条消息可以检查密钥交换和认证过程是否已经成功。其中包括一个校验值,对客户端整个握手过程的消息进行校验。服务器同样发送Change Cipher Spec消息和Finished消息。握手过程完成,客户端和服务器可以交换应用层数据进行通信。
Server Finished:
服务端握手结束通知。
使用私钥解密加密的Pre-master数据,基于之前(Client Hello 和 Server Hello)交换的两个明文随机数 random_C 和 random_S,计算得到协商密钥:enc_key=Fuc(random_C, random_S, Pre-Master);
计算之前所有接收信息的 hash 值,然后解密客户端发送的 encrypted_handshake_message,验证数据和密钥正确性;
发送一个 ChangeCipherSpec(告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和 Session Secret加密数据了)
服务端也会使用 Session Secret 加密一段 Finish 消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功。
SSL会话恢复
会话恢复是指只要客户端和服务器已经通信过一次,它们就可以通过会话恢复的方式来跳过整个握手阶段而直接进行数据传输。
SSL采用会话恢复的方式来减少SSL握手过程中造成的巨大开销。
此功能从原来正常协调的13步,减少到只需要6步,大大减少了SSL VPN隧道建立所需要的开销。
为了加快建立握手的速度,减少协议带来的性能降低和资源消耗(具体分析在后文),TLS 协议有两类会话缓存机制:
会话标识 session ID: 由服务器端支持,协议中的标准字段,因此基本所有服务器都支持,服务器端保存会话ID以及协商的通信信息,Nginx 中1M 内存约可以保存4000个 session ID 机器相关信息,占用服务器资源较多;
会话记录 session ticket :需要服务器和客户端都支持,属于一个扩展字段,支持范围约60%(无可靠统计与来源),将协商的通信信息加密之后发送给客户端保存,密钥只有服务器知道,占用服务器资源很少。
二者对比,主要是保存协商信息的位置与方式不同,类似与 http 中的 session 与 cookie。二者都存在的情况下,(nginx 实现)优先使用 session_ticket。
会话恢复具体过程(Session ID机制):
1.如果客户端和服务器之间曾经建立了连接,服务器会在握手成功后返回 session ID,并保存对应的通信参数在服务器中;
2.如果客户端再次需要和该服务器建立连接,则在 client_hello 中 session ID 中携带记录的信息,发送给服务器;
3.服务器根据收到的 session ID 检索缓存记录,如果没有检索到货缓存过期,则按照正常的握手过程进行;
4.如果检索到对应的缓存记录,则返回 change_cipher_spec与 encrypted_handshake_message 信息,两个信息作用类似,encrypted_handshake_message 是到当前的通信参数与 master_secret的hash 值;
5.如果客户端能够验证通过服务器加密数据,则客户端同样发送 change_cipher_spec 与 encrypted_handshake_message 信息;
服务器验证数据通过,则握手建立成功,开始进行正常的加密数据通信。
会话恢复具体过程( session ticket):
1.如果客户端和服务器之间曾经建立了连接,服务器会在 new_session_ticket 数据中携带加密的 session_ticket 信息,客户端保存;
2.如果客户端再次需要和该服务器建立连接,则在 client_hello 中扩展字段 session_ticket 中携带加密信息,一起发送给服务器;
3.服务器解密 sesssion_ticket 数据,如果能够解密失败,则按照正常的握手过程进行;
4.如果解密成功,则返回 change_cipher_spec 与 encrypted_handshake_message 信息,两个信息作用与 session ID 中类似;
5.如果客户端能够验证通过服务器加密数据,则客户端同样发送 change_cipher_spec与encrypted_handshake_message 信息;
6.服务器验证数据通过,则握手建立成功,开始进行正常的加密数据通信。
SSL原理(记录协议)
SSL记录协议主要用来实现对数据块的分块、加密解密、压缩与解压缩、完整性检查及封装各种高层协议。
每个SSL记录包含以下信息:
- 内容类型
- 协议版本号,目前有2.0和3.0版本
- 记录数据的长度
- 数据有效载荷
- 散列算法计算消息认证代码
详细步骤
(1)将上层分下来的数据包分成合适的数据块,但是每个数据块不得超过214字节。
(2)对每个数据块进行压缩,但是不能丢失数据信息。
(3)计算压缩后的数据消息认证码MAC,并添加在压缩包后。添加后总长度不得超过2262字节。
(4)对于流加密,压缩保额和MAC以前被加密。对于分组加密,在MAC之后,加密之前可以增加填充。填充由表示填充长度的字节和移动数目的填充字节组成,填充字节的数目使得要加密的数据的总长度成为加密分组长度整数倍的最小数目。
(5)给SSL添加一个首部。其中包括:内容类型、主要版本、次要版本、压缩长度等
信息。
通过以上过程把原始的数据加密为SSL协议的记录集。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/100122.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...