本文转载自SSL (Secure Sockets Layer)

TLS简介

The Transport Layer Security (TLS) protocol aims primarily to provide secure and data integrity between two communicating computer applications.

TLS位于TCP之上(也有基于UDP的,称为DTLS,这里不讨论它),如图 1 所示。

Figure 1: SSL/TLS协议所在层次

TLS各个版本提出时间如表 1 所示。

Protocol Published
SSL 1.0 Unpublished
SSL 2.0 1995
SSL 3.0 1996
TLS 1.0 1999
TLS 1.1 2006
TLS 1.2 2008
TLS 1.3 2018

1.1 TLS两个阶段

TLS协议可分为两个阶段:

1、握手(Handshake)阶段,其目的是通信双方约定在数据传输阶段使用的加解密算法及密钥(为效率考虑,在数据传输阶段会使用对称密钥算法);

2、数据传输阶段,即发送到网络前加密数据,从网络收到数据后解密数据。

TLS报文头

TLS报文头占5字节,第1字节是类型(目前有4种类型),第2-3字节是版本(目前有4种版本),第4-5字节是长度(不包含报文头本身长度),其格式为:

         record type (1 byte)
/
/ version (1 byte major, 1 byte minor)
/ /
/ / length (2 bytes)
/ / /
+----+----+----+----+----+
| | | | | |
| | | | | | TLS Record header (5 bytes)
+----+----+----+----+----+ Record Type Values dec hex
-------------------------------------
CHANGE_CIPHER_SPEC 20 0x14
ALERT 21 0x15
HANDSHAKE 22 0x16
APPLICATION_DATA 23 0x17 Version Values dec hex
-------------------------------------
SSL 3.0 3,0 0x0300
TLS 1.0 3,1 0x0301
TLS 1.1 3,2 0x0302
TLS 1.2 3,3 0x0303

TLS 1.2 Handshake

Handshake具体过程

TLS1.2使用“两个来回”完成握手过程:

          TLS1.2 Handshake

          +-----+                              +-----+
| | | |
| | ClientHello | |
| o----------------------------> | |
| | | |
| | | |
| | ServerHello | |
| | [Certificate] | |
| | [ServerKeyExchange] | |
| | [CertificateRequest] | |
| | ServerHelloDone | |
| | <----------------------------o |
CLIENT | | | | SERVER
| | | |
| | [Certificate] | |
| | ClientKeyExchange | |
| | [CertificateVerify] | |
| | ** ChangeCipherSpec ** | |
| | Finished | |
| o----------------------------> | |
| | | |
| | | |
| | ** ChangeCipherSpec ** | |
| | Finished | |
| | <----------------------------o |
| | | |
+-----+ +-----+

下面来介绍一下Handshake的具体过程。

第1步、客户端发送 ClientHello 报文。其主要作用是告诉服务器,本客户端所支持的TLS协议版本,以及所支持的加密算法等等。

第2步、服务器发送 ServerHello 报文。其主要作用是服务器选择一个它认为安全的,且双方都支持的加密算法;如果服务器认为客户端所有支持的加密算法都不安全,则服务器可以发送一个ALERT报文(ALERT报文是TLS顶级报文,参见 1.2 )。

第3步、服务器发送 Certificate 报文。其主要作用是服务器发送自己的证书给客户端。

第4步、服务器发送 ServerKeyExchange 。其主要作用是提供一些信息,以便双方有足够的信息来约定一个数据传输阶段所使用的对称密钥算法的密钥。这个报文是可选的,如果使用Diffie-Hellman方式来约定密钥,则这个是必须的;如果是RSA方式来约定密钥,它可以省略,参见后面介绍的 ClientKeyExchange 报文。

第5步、服务器发送 CertificateRequest 。其作用是开启“双向认证(Mutual authentication)”模式,即不仅客户端要验证服务器,而且服务器还要验证客户端。这种方式在https网站中很少使用,如果对https网站进行抓包分析,一般都不会有这个报文。

第6步,服务器发送 ServerHelloDone 。其作用是告诉客户端

第7步、客户端发送 Certificate 报文(仅当客户端收到了 CertificateRequest 时才发送,即服务器开启了双向认证)。其主要作用是客户端发送自己的证书给服务器。

第8步、客户端发送 ClientKeyExchange 报文。其主要作用是提供一些信息,以便双方有足够的信息来约定一个数据传输阶段所使用的对称密钥算法的密钥。如果是RSA方式,则客户端生成一个对称密钥算法的密钥后,使用服务器的公钥进行加密后传送给服务器。如果是Diffie-Hellman方式,则传送必要信息以便双方可以按约定方式生成同一个密钥。

第9步、客户端发送 CertificateVerify 报文(仅当客户端收到了 CertificateRequest 时才发送,即服务器开启了双向认证)。主要作用是客户端发送一段它签名的信息给服务器,这样服务器使用客户端的公钥就可以验证签名,从而验证客户端。

第10步、客户端发送 ChangeCipherSpec 报文,告诉服务器你可以使用加密模式了。注: ChangeCipherSpec 报文不属于Handshake报文,它是TLS顶级报文。

第11步、客户端发送 Finished 报文,告诉服务器我准备好加密通信了。

第12步、服务器发送 ChangeCipherSpec 报文,告诉客户端你可以使用加密模式了。

第13步、服务器发送 Finished 报文,告诉客户端我准备好加密通信了。至此,握手结束。

单向认证和双向认证

握手阶段,如果服务器发送了 CertificateRequest ,就意味着开启“双向认证”。和“单向认证”相比,“双向认证”在握手阶段多了下面3种报文:

  • 服务器发送的 CertificateRequest
  • 客户端发送的 CertificateCertificateVerify

参考:An Introduction to Mutual SSL Authentication

复用TLS协商结果:Session Identifier, Session Ticket

当我们打开一个https网页时往往会发送几十个请求,难道要重复几十次TLS握手协商吗?当然不用, 有两种方案可以复用第一次请求的TLS协商结果:Session Identifier和Session Ticket。

这里不详细介绍它们,可参考:

https://en.wikipedia.org/wiki/Transport_Layer_Security#Resumed_TLS_handshake

https://stackoverflow.com/questions/19939247/ssl-session-tickets-vs-session-ids

Handshake报文格式

Handshake报文格式如下所示:

                         |
|
|
Record Layer | Handshake Layer
| | |
| | |
+----+----+----+----+----+----+----+----+----+------ - -+----+----+----+----+------ - -+ ......
| 22 | | | | | | | | | | | | | | |
|0x16| | | | | | | | |message | | | | |message |
+----+----+----+----+----+----+----+----+----+------ - -+----+----+----+----+------ - -+
/ /--/--/ | \ \----\-----\ | \ \----\-----\ |
/ / | \ \ \ \
type: 22 / | \ handshake message length \ handshake message length
/ type type
/
length: arbitrary (up to 16k) Handshake Type Values dec hex
-------------------------------------
HELLO_REQUEST 0 0x00
CLIENT_HELLO 1 0x01
SERVER_HELLO 2 0x02
CERTIFICATE 11 0x0b
SERVER_KEY_EXCHANGE 12 0x0c
CERTIFICATE_REQUEST 13 0x0d
SERVER_HELLO_DONE 14 0x0e
CERTIFICATE_VERIFY 15 0x0f
CLIENT_KEY_EXCHANGE 16 0x10
FINISHED 20 0x14

注1:共有10种类型的Handshake报文,每种类型的具体格式可参考:Traffic Analysis of an SSL/TLS Session

注2:多个Handshake报文可以组合为一个TLS Record,上面演示中就有两个Handshake报文。

ClientHello

ClientHello报文如下所示:

     |
|
|
| Handshake Layer
|
|
- ---+----+----+----+----+----+----+------+----+----------+--------+-----------+----------+
| 1 | | | | | |32-bit| |max 32-bit| Cipher |Compression|Extensions|
|0x01| | | | 3 | 1 |random| |session Id| Suites | methods | |
- ---+----+----+----+----+----+----+------+----+----------+--------+-----------+----------+
/ | \ \---------\ \----\ \ \
/ \ \ \ \ SessionId
record \ length SSL/TLS \
length \ version SessionId
type: 1 (TLS 1.0 here) length CipherSuites +----+----+----+----+----+----+
| | | | | | |
| | | | | | |
+----+----+----+----+----+----+
\-----\ \-----\ \----\
\ \ \
length cipher Id cipherId Compression methods (no practical implementation uses compression) +----+----+----+
| | | |
| 0 | 1 | 0 |
+----+----+----+
\-----\ \
\ \
length: 1 cmp Id: 0 Extensions +----+----+----+----+----+----+----- - -
| | | | | | |
| | | | | | |...extension data
+----+----+----+----+----+----+----- - -
\-----\ \-----\ \----\
\ \ \
length Extension Extension data
Id length

Server Name Indication (SNI)

在TLS握手时,客户端发送的ClientHello中不包括服务器的域名,这一般不会有问题。但随着HTTP服务器开启虚拟主机支持后,每个服务器通过相同的IP地址可以为很多个网站提供服务。这样服务器在发送Certificate报文时不知道应该向客户端提供哪一个网站的证书。2006年,TLS协议增加了Server Name Indication (SNI) 扩展,允许客户端在ClientHello报文中带上它所请求的域名,这样服务器就知道客户端想访问哪个网站了,从而提供对应的证书。

参考:https://blog.csdn.net/makenothing/article/details/53292335

Application Layer Protocol Negotiation (ALPN)

Application Layer Protocol Negotiation (ALPN, RFC 7301),旨在将原来应用层协议中的协商,提前合并到TLS握手时完成,以减少一次往返时间(即不再需要应用层协议中的协商了)。

ALPN最初是为Google SPDY协议(现已标准化为HTTP/2)而提出的。我们以HTTP/2为实例来说明ALPN。假设TLS握手完成了,接下来客户端和服务端就应该开始进行正常的HTTP通信了,但是客户端认为HTTP协议比较慢,在请求内容之前先向服务端提出“我们能不能使用HTTP/2协议”。服务端会根据自己支持HTTP/2的情况给出回答,之后客户端会根据服务端的答复,使用HTTP或HTTP/2向服务端请求内容。可以看到这个过程中又多了一次协商升级协议的往返,导致客户端拿到返回结果的延迟更大了。

为了优化这一点,在HTTP使用TLS加密的时候,会使用ALPN扩展,把升级HTTP协议的请求放在ClientHello的ALPN Extension字段中,服务端在ServerHello的ALPN Extension字段中回复说“我支持HTTP/2”。这样TLS握手之后,客户端就可以直接按HTTP/2发起请求而不必多一次往返了。

ALPN 检测服务器是否支持 HTTP 2

前面说过,在 TLS 握手阶段,客户端可通过 ALPN 来检测服务器是否支持 HTTP 2。下面以浏览器访问 “https://tmail.com” (它已经支持了HTTP 2)为例,使用 Wireshark 进行抓包验证。

浏览器第一次发送 ClientHello 报文时,在 ALPN 中携带了浏览器支持的版本,h2 代表浏览器支持 HTTP 2 协议,如图 2 所示。

Figure 2: ClientHello

服务器在返回 ServerHello 报文时,在 ALPN 中返回了 h2,表示服务器支持 HTTP 2 协议,如图 3 所示。

Figure 3: ServerHello

这样,建立 TLS 连接后,浏览器就知道了服务器已经支持 HTTP 2,下一步,可以直接发送“GET / HTTP/2”这样的 HTTP 报文了。

TLS 1.3

2018年8月10日,IETF发布了TLS 1.3(RFC 8446)。这次是TLS协议的第一次重大改革,带来了重大的安全性和性能改进。

TLS 1.3 只需要一个RTT(来回传输一次的时间)就能完成握手,相比TLS 1.2省去了一个RTT(如图 45 所示,图片摘自:https://www.cloudflare.com/learning-resources/tls-1-3/ )。并且TLS 1.3支持“0-RTT”模式,在该模式下客户端可以在握手的同时发送数据,极大地加快了https网页的加载速度。

Figure 4: TLS 1.2握手完成需要“来回两次”

Figure 5: TLS 1.3握手完成仅需“来回一次”

参考

The Transport Layer Security (TLS) Protocol Version 1.2

Traffic Analysis of an SSL/TLS Session

使用wireshark观察SSL/TLS握手过程--双向认证/单向认证

SSL (Secure Sockets Layer)的更多相关文章

  1. Secure Sockets Layer(安全套接层)

    SSL SSL(Secure Sockets Layer安全套接层)及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议.TL ...

  2. SSL介绍(Secure socket Layer & Security Socket Layer)

    一个应用程序的安全需求在很大程度上依赖于将如何使用该应用程序和该应用程序将要保护什么.不过,用现有技术实现强大的. 一般用途的安全通常是可能的.认证就是一个很好的示例. 当顾客想从 Web 站点购买某 ...

  3. nginx配置ssl证书的方法

    Nginx (读音"engine x") 是一个高性能的HTTP和反向代理服务器,比Apache占用更少的内存,同时也像Apache一样支持HTTPS方式访问(SSL加密).本教程 ...

  4. 为你的Android App实现自签名的 SSL 证书(转)

    介绍 网络安全已成为大家最关心的问题. 如果你利用服务器存储客户资料, 那你应该考虑使用 SSL 加密客户跟服务器之间的通讯. 随着这几年手机应用迅速崛起. 黑客也开始向手机应用转移, 原因有下列3点 ...

  5. 【转】SSL协议、SET协议、HTTPS简介

    一.SSL协议简介 SSL是Secure Socket Layer的缩写,中文名为安全套接层协议层.使用该协议后,您提交的所有数据会首先加密后,再提交到网易邮箱,从而可以有效防止黑客盗取您的用户名.密 ...

  6. 那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)

    之前没接触过证书加密的话,对证书相关的这些概念真是感觉挺棘手的,因为一下子来了一大堆新名词,看起来像是另一个领域的东西,而不是我们所熟悉的编程领域的那些东西,起码我个人感觉如此,且很长时间都没怎么搞懂 ...

  7. tomcat配置SSL双向认证

    一.SSL简单介绍 SSL(Secure Sockets Layer 安全套接层)就是一种协议(规范),用于保障客户端和服务器端通信的安全,以免通信时传输的信息被窃取或者修改. 怎样保障数据传输安全? ...

  8. SSL、OPENSSL、SSH、OPENSSH

    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议.TLS与 ...

  9. MySQL(MariaDB)的 SSL 加密复制

    背景: 在默认的主从复制过程或远程连接到MySQL/MariaDB所有的链接通信中的数据都是明文的,在局域网内连接倒问题不大:要是在外网里访问数据或则复制,则安全隐患会被放大很多.由于项目要求需要直接 ...

随机推荐

  1. 小白的springboot之路(十九)、集成swagger(com.spring4all篇)

    0-前言 集成swagger,有两种方式: 一种在前面已经介绍过了,直接集成官方的springfox-swagger2的方式,这种方式需要在配置类中配置 第二种方式是这里要介绍的方式,国人写的com. ...

  2. SSM、SSH框架搭建,面试点总结

    文章目录 1.SSM如何搭建:三个框架的搭建: 2.SSM系统架构 3.SSM整合步骤 4.Spring,Spring MVC,MyBatis,Hibernate个人总结 5.面试资源 关于SSM.S ...

  3. Java 8新特性(Lambda,Stream API)

    由于最近总监要求学习Java 8的一些知识,就去网上找了 一套教程来学习学习,将学习结果做一个小的总结记录,方便以后使用: 1.Java 8的优点 2.Lambda表达式优点 2.1Lambda实例 ...

  4. Spring boot AOP 实现Redis 存储

    package com.carloan.common.web.annotation; import java.lang.annotation.*; /** * 自定义redis缓存注解.只要在serv ...

  5. python--函数、参数、名称空间与作用域、匿名函数、内置函数、闭包

    python函数 函数定义 def welcome(): print('hello world!!') welcome() #函数调用 ...运行结果 hello world!! 函数定义和编写原则: ...

  6. StringTable---字符串常量池的垃圾回收跟踪案例

    引言 很多人认为jvm字符串常量不会被回收的,其实这个说法的有误区的,我们通过一些jvm参数可以看到StringTable的垃圾回收. 案例说明 参数说明 参数 说明 -Xmx10m 堆空间大小 -X ...

  7. 在线工具生成接入信息mqtt.fx快速接入阿里云

    在线工具生成接入信息mqtt.fx快速接入阿里云 在使用阿里云获取的三元组信息进行接入的时候,往往需要加密生成接入信息之后才能进行接入,因此我根据阿里云提供的加密工具实现了一个阿里云物联网平台mqtt ...

  8. 2019 徐州网络赛 M Longest subsequence t

    对于答案来说,一定是 前 i-1 个字符和 t的前 i 个一样,然后第 i 个字符比 t的 大 \(i\in [1,m]\) 前缀为t,然后长度比t长 对于第一种情况,枚举这个 i ,然后找最小的 p ...

  9. hdu4352 XHXJ's LIS (数位dp)

    Problem Description #define xhxj (Xin Hang senior sister(学姐))  If you do not know xhxj, then careful ...

  10. 错误: 未能完成程序集的安装(hr = 0x8007000b)。探测终止。

     解决方案:VS中"工具"->"选项"->"Web项目"->"对网站和项目使用IIS Express的64位版& ...