SSL/TLS
SSL/TLS Protocol
Secure Sockert Layer/Transport Layer Security
两层协议
握手协议 | 密码改变协议 | 告警协议 记录协议
SSL 记录协议负责对上层的数据进行分块、压缩、计算并添加 HMAC 、加密(先压缩再加密)
内容类型 | 主版本号 | 子版本号 | 压缩长度 压缩数据 消息认证码
HTTPS 通信过程
TCP 三次握手 SYN, ACK 的含义:TCP
Client Server | -----SYN----> | | <--SYN+ACK--- | | -----ACK----> | Client Server
SSL 握手(TLS 1.2 - RFC5246)
Client Server ClientHello ------> ServerHello Certificate* ServerKeyExchange* CertificateRequest* <------ ServerHelloDone Certificate* ClientKeyExchange CertificateVerify* [ChangeCipherSpec] Finished ------> [ChangeCipherSpec] <------ Finished
4 messages as 2 RTT(Round-Trip Time). 使用 Wireshark 抓包分析:HTTPS 取证
承载应用层 HTTP 协议
Client Server Application Data <-----> Application Data
SSL Handshake 阶段交换的信息
ClientHello:
- TLS Version
- Client Random
- (Sessio ID)
- Cipher Suites
ServerHello:
- TLS Version
- Server Random
- Session ID
- Cipher Suite
- (Extension)
Certificate: 服务器的数字证书,一般都是单向认证,除非服务器附带 CertificateRequest
以请求验证客户端的证书
ServerHelloDone: 服务器的 HELLO 结束
ClientKeyExchange:
- PriKey_Server {pre-master} ,即使用服务器公钥加密的 pre-master
ChangeCipherSpec: 告诉对方开始使用对称加密的会话密钥进行通信
Finished: Encrypted Handshake Message ,把之前所有发送的数据通过摘要算法计算摘要,再使用会话密钥(master secret)加密,方便服务器验证加密通信是否可用和之前的握手信息是否被篡改
ssl3_send_client_key_exchange 是 openssl 中客户端确定密钥的函数,同时也发送了“一部分”数据给服务器,这一部分数据就是所谓的 pre_master ,不管是客户端还是服务器都根据对端传过来的 pre_master 和自己计算出来的另一部分数据来生成最终的对称密钥,生成过程中需要 hello 消息中的随机数,这样生成的密钥才不会每次都一样。由于 ssl 协议中 dh 份额来源于证书,而证书又是静态的,因此十分有必要引入一种随机因素来保证通过静态证书导出的密钥份额协商出来的密钥的随机性。同时这也是 pre_master 的意义,那就是随机,对于 rsa 密钥交换算法来说, pre-master-key 本身就是一个随机数,再加上 hello 消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥,但是对于 dh ,包括 ecdh 算法(不考虑匿名 dh 和瞬时 dh),就只有 hello 消息中的两个随机数因子了。 pre master 的存在在于 ssl 协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么 pre master secret 就有可能被猜出来,那么仅适用 pre master secret 作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上 pre master secret 三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。
SSL Cipher
例如: TLS_RSA_WITH_AES_128_GCM_SHA256
是由 密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法 组成。
一般 WITH
前的那一部分由两部分组成,第一部分约定密钥交换算法,第二部分约定证书的验证算法,此例中只有 RSA
说明握手时密钥交换算法和签名算法都是使用 RSA
。
握手完成后,使用 AES
的 GCM
分组模式进行对称加解密。
摘要算法 SHA256
用于消息认证和产生随机数。
但是用 RSA 算法协商会话密钥的方法不能保证前向安全,一旦服务器的私钥泄漏,过去被第三方截获的所有 SSL/TLS 通讯密文都会被破解。
离散对数 DH 算法
Discrete Logarithm - 离散对数
通信双方 Alice 和 Bob 需要确定模数和底数作为算法的参数,即 P 和 G。
Alice: \(A \equiv G^{a} \mod P\)
Bob: \(B \equiv G^{b} \mod P\)
Alice -> Bob: A , P, G
Bob -> Alice: B
Alice: Calculate \(B^{a} \mod P\) 得到 K ,
Bob: Calculate \(A^{b} \mod P\) 同样也是得到 K ,于是双方以 K 作为会话密钥进行通信。
离散对数的幂运算满足交换律, \[B^{a} \mod P & \equiv (G^{b})^{a} \mod P \equiv (G^{a})^{b} \mod P \equiv A^{a} \mod P\]
此算法在服务器固定 DH 公私钥时被称为 static DH ,现在已经基本不用了,转而使用 DHE(Diffie Hellman Ephemeral) 算法,即双方每次通信时都随机生成一对公私钥。
DHE 密钥交换
Diffie Hellman
工作流程(简略版,需要考虑中间人攻击,在数字证书体系下,是可以防止中间人攻击的):
Client Server Hello ------> (Generate PriKey_S and PubKey_S) Hello PubKey_S <------ Certificate* (Generate PriKey_C and PubKey_C) PubKey_C Finished ------> PubKey_S + PriKey_C -> master <- PubKey_C + PriKey_S <------ Finished
每一次通讯的 PriKey, PubKey 都是实时生成的, PriKey 存在于内存中,不会出现在 TLS 报文中,若不知道当时的私钥 PriKey 则无法破解当时的 TLS 加密报文。
ECDHE
提高 DHE 的性能,使用 ECC 椭圆曲线的特性计算公钥及会话密钥。过程:
- Alice 和 Bob 事先确定好使用哪种椭圆曲线(曲线方程),以及曲线上的基点 G 点,公开传输
- Alice 和 Bob 各自随机生成一个随机数作为私钥 a, b,并与基点相乘得到公钥 A = aG, B = bG
- 双方各自交换公钥 A, B ,Alice 计算点 (x_{a}, y_{a}) = aB ,Bob 计算点 (x_{b}, x_b) = bA 由于椭圆曲线满足乘法交换律和结合律,所以 aB = abG = baG = bA ,所以双方计算得到的点是一样的,可作为会话密钥
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
握手解析:
- C -> S:
- Client Hello
- Version
- Random_C
- Cipher Suites
- Client Hello
- S -> C:
- Server Hello
- Version
- Random_S
- Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 密钥协商 ECDHE; 签名算法 RSA; 对称加密 AES256GCM; 摘要算法 SHA384
- Extensions
- Certificate
- Server Key Exchange
- EC Diffie-Hellman Params
- Curve Type
- Named Curve
- PubKey_S
- Signature 利用 RSA 算法对 PubKey_S 进行签名,防止中间人攻击
- EC Diffie-Hellman Params
- Server Hello Done
- Server Hello
C -> S:
- Client Key Exchange
- EC Diffie-Hellman Client Params
- PubKey_C
- EC Diffie-Hellman Client Params
- Change Cipher Spec(Change Cipher Spec Protocol)
- Encrypted Handshake Message 将之前发送所有消息做一个摘要,再用会话密钥加密 会话密钥由 Random_C, Random_S, K 共同生成
这一步后客户端就可以开始发送上层协议的数据了 (TLS False Start)
- Client Key Exchange
- S -> C:
- Change Cipher Spec(Change Cipher Spec Protocol)
- Encrypted Handshake Message
在 ECDHE 过程中,双方的 临时私钥 在内存的存在时间非常短(毫秒),可近似认为满足 PFS(Profect Forward Security) 。
与 RSA 的比较:RSA 密钥交换实际上是 Key Transmission , Session Key 在客户端侧产生,然后通过服务器的证书公钥加密后发送给服务器,而 DHE 双方都会计算出 Session Key ,并且相关部分参数只存在于内存中,不会出现在报文中,满足前向安全。
DHE 安全性论文:
@misc{cryptoeprint:2011/219, author = {Tibor Jager and Florian Kohlar and Sven Schäge and Jörg Schwenk}, title = {On the Security of TLS-DHE in the Standard Model}, howpublished = {Cryptology ePrint Archive, Paper 2011/219}, year = {2011}, note = {\url{https://eprint.iacr.org/2011/219}}, url = {https://eprint.iacr.org/2011/219} }
TLS session resumption
Session ID 和 Session Ticket 都不满足前向安全,一旦加密会话密钥的密钥被破解或泄漏,前面被截获的报文都会被破解。以下三种会话复用技术都且无法抵御重放攻击。
Session ID
客户端和服务器首次 TLS 握手建立连接后,双方在内存中缓存会话密钥,并用唯一的 Session ID 来表示,即 Session ID 作为 key ,会话密钥作为 value 。 当客户端再次连接时,在 HELLO 消息中带上 Session ID ,服务器收到后就会从内存找到该会话密钥,在 1 个 RTT 中建立 TLS 通信。 Session ID 定期失效。
问题: 服务器需要额外的资源保存 Session ID ,占用内存资源。 面对负载均衡的情况,无法保证客户端的连接会命中上次访问过的服务器。
Session Ticket
客户端和服务器首次 TLS 握手建立连接后,服务器会将会话密钥加密后作为 Ticket 发送给客户端,由客户端缓存该 Ticket。 当客户端再次连接时,会发送 Ticket ,服务器解密后就可以获取上一次的会话密钥,验证有效期后无问题就可以建立 TLS 通信。
Pre-shared Key
类似 Session Ticket ,但可以直接在 HTTP 请求中带上 Pre-shared Key ,在 0 RTT 内恢复会话。
TLS Extension
ALPN
ALPN(Application Layer Protocol Negotiation) 是 TLS 的扩展,允许在安全连接的基础上进行应用层协议的协商。ALPN 支持任意应用层协议的协商,目前应用最多是 HTTP2 的协商。在 2016 年, ALPN 已经完全替代 NPN 了。
#+begin_quote ALPN allows the application layer to negotiate which protocol to use over the secure connection. Any protocol can be negotiated by ALPN within a TLS connection. The protocols that are most commonly negotiated are HTTP/2 (for browsers that support it) and, historically, SPDY. The ALPN implementation is therefore not HTTP/2 or SPDY specific in any way. #+end_quote+
Digital Certificate
key 通常指私钥。
CSR, Certificate Signing Request ,即证书签名申请,这不是证书,这是要求 CA 给证书签名的一种正式申请,该申请包含申请证书的实体的公钥及该实体的某些信息。该数据将成为证书的一部分。CSR 始终使用它携带的公钥所对应的私钥进行签名。
CRT, certificate ,即证书
X.509,一种证书格式。对 X.509 证书来说,认证者总是 CA 或由 CA 指定的机构,一份 X.509 证书是一些标准字段的集合,这些字段包含有关用户或设备及其相应公钥的信息。
X.509 的证书文件,一般以 .crt 结尾。
PEM, Privacy Enhanced Mail,以 “-----BEGIN...” 开头, “-----END...” 结尾,内容是 BASE64 编码。
Reference
- 图解网络-小林 coding-v3.0.pdf