原理-TLS1.2及之前的版本
协议握手,建立会话
-
客户端 Hello 消息,携带以下信息
- 协议版本,目前有 sslv2,sslv3,tls1.0,tls1.1,tls1.2,tls1.3
- 客户端产生的随机数,用于后面生成会话 key
- 客户端支持加密算法列表,按优先级从高到低排序
-
服务器 Hello 消息,携带以下信息
-
ssl 证书
-
服务器选择的加密算法,根据客户端发送的加密算法列表,和服务器端支持的加密算法,取交集,取优先级最高的;可能跟具体的软件实现也有关系
-
服务器端产生的随机数,用于后面产生会话 key
-
-
客户端验证服务器的 ssl 证书
-
协商一些加密算法的参数,比如 椭圆曲线类的加密算法,会协商一些额外的加密相关的参数
-
根据密钥交换协议和加密算法协议,和服务器端协商出一个 预主密钥
-
-
生成会话 key
- 从 客户端随机数,服务器随机数,预主密钥 生成会话 key
-
客户端和服务器使用 会话 key 通信
密钥交换协议
- 目前主要的密钥交换协议,相关的密钥交换协议又有各自的变体和增强
- RSA
- 静态的RSA算法,在 TLS1.3 中已经禁止
- DH
- TLS1.3 中全面使用 ECDHE
- PSK
- TLS1.3 新增,用于复用之前的会话 key,减少连接建立时间,但是会缺乏前向安全性
- RSA
- RSA 和 DH 不同的地方,主要是在 如何生成 预主密钥,参看 https://www.cloudflare.com/zh-cn/learning/ssl/what-happens-in-a-tls-handshake/
加密套件的写法
- RFC 和 不同的软件实现,有不同的描述方式,但是实际的 16 进制编码是一致的
示例参看 https://ciphersuite.info/cs/TLS_PSK_WITH_3DES_EDE_CBC_SHA/ - 加密套件的写法中,一般主要包括 3 个内容
- 密钥交换算法,主要用于证书认证,协商加密算法,生成 预主密钥等
- 又可以细分为
- 密钥交互算法,如RSA, ECDHE, ECDH, SRP 等
- 证书认证算法,比如 DSA, ECDSA, RSA, PSK 等,DSA 证书在 TLS1.3 中禁用
- 如果不能识别,则使用 openssl ciphers -v 查看,或者上网查询
- 又可以细分为
- 加密算法,即根据会话 key 加密消息的算法
- 又可细分为
- 加密算法,如 AES-128, AES-256,SEED 等
- 加密模式,如 GCM, CBC, CBC3 等
- 如无法识别,可以使用 openssl ciphers -v 来确认,或者上网查看
- 又可细分为
- 摘要算法,用于对 ssl 会话中的 协议消息,数据消息,计算摘要和签名,保证信息的完整性
- 密钥交换算法,主要用于证书认证,协商加密算法,生成 预主密钥等
- 由于在加密套件的写法中,对于上述的 3 点没有明显的分隔符,因此在解读不同的加密算法套件,需要自行上网查询,确认当前加密算法套件中的 密钥交换算法,加密算法,摘要算法
- 也可以使用 openssl ciphers -v 来查看加密套件,所使用的密钥交互算法/加密算法/摘要算法
- 使用 curl, haproxy 这些软件时,要注意,加密算法的参数都是直接传递给 ssl 协议实现的后端的
- 目前 linux 上主要使用的 ssl 协议
- openssl, 可以使用 openssl ciphers 查看支持的加密套件
- 目前已知 ubuntu 16.04 上的 haproxy 使用 openssl 编译
- 加密算法套件的说明,见 man ciphers
- gnutls,可以使用 gnutls-cli -l 查看支持的加密套件
- 目前已知 ubuntu 16.04 上的 curl 使用gnutls 编译
- openssl, 可以使用 openssl ciphers 查看支持的加密套件
- 在处理 ssl 会话建立失败时,要注意不同的 ssl 协议实现的区别
- 目前 linux 上主要使用的 ssl 协议