Featured image of post SSL/TLS 速问速答

SSL/TLS 速问速答

近期学习SSL/TLS的总结,速问速答。

[TOC]

为什么需要 SSL/TLS,与 HTTP、HTTPS 的关系

因为 HTTP 的设计是存在缺陷的。比如 HTTP 协议传递明文,攻击者很容易获取到明文数据,造成信息泄露;协议标准没有验证对端的身份,容易被冒充;协议没有对消息进行完整性校验,数据容易被篡改。

HTTPS 相比于 HTTP 多了一个 S,即 Secure,而 HTTPS 又被称为 HTTP over SSLHTTP over TLSHTTP Secure

所以,可以理解为 HTTPS = HTTP + SSL/TLS。

HTTPS 使用 HTTP 协议进行通信,使用 SSL/TLS 才解决 HTTP 存在的缺陷(数据未加密、身份验证和消息完整性校验)。

SSL/TLS 协议的发展历史

SSL 即 Secure Sockets Layer, 安全套接字层。

TLS 即 Transport Layer Security,传输层安全协议。

可以理解为 SSL 是 TLS 的前身(目前使用最多的也是 TLS v1.2 和 TLS v1.3)。

SSL 有三个版本 v1.0,v2.0,v3.0。

SSL 最初由网景公司为解决 HTTP 安全问题设计,第一版 v1.0由于涉及本身存在安全漏洞而被抛弃,此版本未公开和使用过;

1995年 SSL 2.0发布,后来也被弃用了。1996年 发布SSL v3.0 是目前 SSL 使用的版本(但是也有浏览器禁用SSL v3.0,因为不安全),但那也够老的了。

TLS v1.0 是 SSL v3.0的升级版,版本变动不大。至于为什么会突然改名字叫TLS,那是因为网景和微软存在竞争,为了取悦微软而改的名字(据说)。

TLS v1.2 和 TLS v1.3是目前使用最多的,TLS v1.3发布于2018年,是目前最新的版本。

简述 SSL/TLS 协议

HTTP 明文传输不安全

我们得让它安全,保证数据机密性和完整性

简单点,对明文进行加密

加密需要 密钥和密码算法

涉及 如何让双方都知道密钥和密码算法

默认固定?那不行,容易被窃听、破解和冒用等等

因而,需要双方商量一下密钥和密码算法

于是,也就需要确定一下商量的方式(密钥协商)

协商的过程,对方有可能被别人冒充

所以,还需要一种证明对方是可信任的方法(身份验证)

“让双方都知道密钥和加密算法”有两种方式,

一种是某一方生成密钥,然后发送给对方(RSA)

另一种是,使用约定的算法,传递算法的输入参数,各自按照算法生成密钥(DH、ECDHE…..)

这些加密算法、协商算法都本质上都需要双方都支持才行,所以双方一定要告诉对方自己支持那些算法

把整个过程用到的密码算法捆绑一起,就成了密码套件

SSL/TLS 协议构成

SSL/TLS 协议分为握手层和记录层。握手层包含有握手协议、告警协议、密钥规格变更协议和应用数据协议。

1
2
3
4
5
+----------+-----------+-----------------+-------------+
| 握手协议  |   警报协议  |  密钥规格变更协议 | 应用数据协议  |
+----------+-----------+-----------------+-------------+
|                     TLS 记录层协议                     |
+------------------------------------------------------+

TLS 记录层的作用

记录层为上层应用层协议提供密码学保护,保障数据的机密性、完整性。

TLS 握手层的作用

握手层为记录层提供密码学算法需要的参数,比如加密算法、密钥等。

简述SSL/TLS 握手协议过程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
  Client                                               Server

      ClientHello                  -------->
                                                      ServerHello
                                                     Certificate*
                                               ServerKeyExchange*
                                              CertificateRequest*
                                   <--------      ServerHelloDone
      Certificate*
      ClientKeyExchange
      CertificateVerify*
      [ChangeCipherSpec]
      Finished                     -------->
                                               [ChangeCipherSpec]
                                   <--------             Finished
      Application Data             <------->     Application Data

由客户端发起握手,在Hello消息中携带TLS 的版本、支持的套件和随机数、SessionID(或Session Ticket)等信息;

服务端回答ServerHello,告诉用什么版本LTS版本,选择什么密码套件和自己生成的随机数;

服务端可以接着发送证书(可选的),然后密钥变更交换生成预备主密钥需要的信息;

双向认证的话,客户端还需要发送自己的证书给服务器端验证;

客户端发送CilentKeyExchange交换生成预备主密钥的信息;

ChangeCipherSpec接着开始告诉对方接下要开始使用密码算法通信了;

Finished就握手完成,Finished是第一个加密的子消息,之前的消息都是明文传递也没有完整性校验,因此在Finished还有一个verify_data环节,校验之前的数据有没有被篡改;

接下来就是使用加密算法加密应用数据传输了。

密钥交换

密钥交换的目的是为了交换预备主密钥(premaster secret),而预备主密钥又是生成主密钥的输入。

密钥交换的方法在密码学中主要是使用非对称加密算法。有 RSA算法、Diffie-Hellman算法、临时DH算法、椭圆曲线DH算法……

算法不同,密钥交换的过程传递的信息也不一样。比如使用RSA时传递的是 使用服务器端公钥加密的预备主密钥,而椭圆曲线算法传递的是算法需要的参数。

随机数、预备主密钥和主密钥的生成

随机数的作用是作为生成预备主密钥和主密钥的输入。

预备主密钥的作用是作为生成主密钥的输入。

主密钥一共 48字节,即有时候说的会话密钥,对称加密密钥。

客户端的随机数在ClientHello子消息中携带给服务器端,服务器的随机数在ServerHello子消息中携带给客户端。

预备主密钥的生成与密钥协商算法有关,如果是RSA那么就由客户端生成,然后使用服务器端的公钥加密在ClientKeyExchange发送给对方。如果是DH或者ECDHE等算法,那么发送的是算法的参数,预备主密钥由双方根据算法各自生成。

主密钥的生成,PRF函数由协商的密码套件决定:

1
2
3
4
master_secret = PRF(pre_master_secret,
                    "master secret",
                    ClientHello.random + ServerHello.random)
                    [0..47];

在此还需要提一下密钥块(key block),这些密钥块是记录层需要的:

1
2
3
4
key_block = PRF(SecurityParameters.master_secret,
                "key expansion",
                SecurityParameters.server_random   +   SecurityParameters.
client_random);

密码套件

整个 SSL/TLS 协议涉及很多密码学的内容。但总的来说就是为了解决几件事:

  • 用什么密码算法加密

  • 双方怎么知道加密算法的密钥

  • 保证消息完整性的Hash算法

  • 身份验证算法

密码套件就是说明了双方使用什么密钥交换算法来协商出预备主密钥,用什么身份验证算法,加密数据的算法的相关信息(强度、模式等)以及HMAC和PRF函数。

会话恢复

两种方式:基于SessionID和Session Ticket。都是在ClientHello带上Session的信息,对于SessionID是直接包含在ClientHello子消息中,对于Session Ticket 是TLS扩展。

基于SessionID即服务器端根据SessionID以键值方式存储会话信息。

基于Session Ticket则是服务器端生成票据加密后发送给客户端,客户端会话恢复时带上票据,服务端解密得到会话信息。服务器端本身不存在会话信息。

Licensed under CC BY-NC-SA 4.0
哦吼是一首歌。
Built with Hugo
Theme Stack designed by Jimmy