wiki/网络/TCPIP/TLS.md
2025-01-02 10:46:09 +08:00

285 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## **一、从HTTPS讲起**
HTTP 本身不具备加密的功能,所以也无法做到对通信整体(使用 HTTP 协议通信的请求和响应的内容)进行加密。
HTTP之所以会被HTTP取代最重要的原因就是不安全。为什么不安全——按传输层 TCP/IP 协议族的工作机制通信内容在所有的通信线路上都有可能遭到窥视。而HTTP 在传输数据的过程中,所有的数据都是明文传输,非常奔放,自然没有安全性可言。数据在公网上传输,容易被第三方获取,尤其特别是一些敏感数据,比如用户密码和信用卡信息等,一旦被第三方获取,后果不堪设想。
HTTPS 主要用于解决数据安全传输的问题,通过加密套件,让数据在网络传输过程中对第三方“不可见”(看见的是无意义的乱码信息)。在 HTTPS 中,原有的 HTTP 协议会得到 TLS (安全传输层协议) 或其前辈 SSL (安全套接层) 的加密。因此 HTTPS 也常指 HTTP over TLS 或 HTTP over SSL。
也就是说 HTTPS = HTTP + SSL / TLS。
![img](../images/TCPIP/tls-1.png)
SSL/TLS是一个介于HTTP协议和TCP协议之间的可选层。
SSLSecure Socket Layer安全套接字层由Netscape公司研发用于确保数据在网络之上传输过程不会被截取当前版本为3.0。
TLSTransport Layer Security传输层安全协议则是由IETFInternet Engineering Task ForceInternet工程任务组纳入标准化的一种新的协议它建立在SSL 3.0协议规范之上是SSL 3.0的后续版本可以理解为SSL 3.1。
![img](../images/TCPIP/tls-2.jpeg)
SSL/TLS协议能够提供的安全目标主要包括如下几个
- 认证性——借助数字证书认证服务器端和客户端身份,防止身份伪造
- 机密性——借助加密防止第三方窃听
- 完整性——借助消息认证码(MAC)保障数据完整性,防止消息篡改
- 重放保护——通过使用隐式序列号防止重放攻击
简单的说SSL/TLS就是一套协议为客户端和服务器之间通信约定和交换密钥提供了可靠的机制。
### **二、SSL/TLS 及其协议格式**
SSL/TLS协议被设计为一个两阶段协议分为握手阶段和应用阶段
- 握手阶段也称协商阶段,在这一阶段,客户端和服务器端会认证对方身份(依赖于PKI体系利用数字证书进行身份认证)并协商通信中使用的安全参数、密码套件以及MasterSecret。后续通信使用的所有密钥都是通过MasterSecret生成。
- 在握手阶段完成后,进入应用阶段。在应用阶段通信双方使用握手阶段协商好的密钥进行安全通信。
SSL/TLS协议有一个高度模块化的架构分为很多子协议如下图所示
![img](../images/TCPIP/tls-3.jpeg)
握手层:
- SSL握手协议包括协商安全参数和密码套件、服务器身份认证(客户端身份认证可选)、密钥交换;
- SSL握手密钥参数更换协议一条消息表明握手协议已经完成
- SSL告警协议对握手协议中一些异常的错误提醒分为fatal和warning两个级别fatal类型的错误会直接中断SSL链接而warning级别的错误SSL链接仍可继续只是会给出错误警告
记录层:包括对消息的分段、压缩、消息认证和完整性保护、加密等。
- 数据分片
- 数据压缩记录/解压缩
- 数据加密规约/负载保护
### **三、SSL/TLS 握手过程详解**
#### **原理详解**
![img](../images/TCPIP/tls-4.jpeg)
首先得完成传输层的握手然后进入SSL握手阶段
**1、ClientHello**
客户端发送Client Hello Message表明自己可以使用的SSL版本、以及相应参数。
- client_versionSSL版本。客户端会从高到低去尝试填入自己支持的SSL版本例如这里就是SSLv3.0。
- random客户端随机数。客户端的随机字符序列用于后续协商密钥。
- session_id本次会话ID。用于后面恢复会话。如果没有会话ID则这里可以为空。
- cipher_suites支持的加密套件列表。根据客户端想要使用的且自己支持的加密套件由高到低排序。
- compression_methods压缩算法列表。根据客户端想要使用的且自己支持的压缩算法由高到低排序。可以为null表示不要压缩。
**2、ServerHello**
【Server Hello】
服务器接受到ClientHello后会返回ServerHello。服务器从客户端在ClientHello中提供的密码套件、SSL/TLS版本、压缩算法列表里选择它所支持的项并把它的选择包含在ServerHello中告知客户端。
ServerHello中同样会包含一个随机数同样4+28 字节类型,由服务器生成。
- server_version服务器支持的SSL版本。例如这里就是SSLv3.0。
- random服务器随机数。服务器端的随机字符序列用于后续协商密钥。
- session_id本次会话ID。如果服务器找到了客户端传过来的session_id会话并且可以恢复会话那么这里会填入和Client Hello相同的session_id否则这里将填入新session_id
- cipher_suite密钥套件。服务器支持的且是从客户端给的列表中选的密钥套件。
- compression_method压缩算法。服务器支持的且是从客户端给的列表中选的压缩算法。
接下来SSL协议的建立就基于服务器选择的密码套件类型、SSL/TLS协议版本以及压缩算法。
**3、Server -> ClientCertificate、Server Key Exchange、Certificate Request、ServerHello Done**
【Certificate*】[服务器证书](https://cloud.tencent.com/product/ssl?from_column=20065&from=20065)
和所选密钥套件中密钥交换算法Key Exchange匹配的用于客户端验证服务器身份和交换密钥的X.509证书。
【Server Key Exchange*】服务器密钥交换信息
如果服务器没有证书或者服务器的证书仅用来签名如DSS证书、签名RSA证书或者使用的是FORTEZZA KEA密钥交换算法现在已经不用了不需要去了解那么就需要发送这条消息。
【Certificate Request *】证书请求
要求客户端也发送它的证书,让服务端校验客户端的身份。
【Server Hello Done】服务器Hello阶段结束信息
一条简单的表明状态的空消息。
**3、客户端校验服务端身份**
【校验服务器身份】
客户端会校验服务器发过来的证书的合法性,包括:
- 证书链的可信性
- 证书是否被吊销
- 证书是否处于有效期
- 证书的域名是否和当前访问域名匹配
如果发现证书不合法,客户端可以发起告警信息。
**4、Client --> ServerCertificate Verify、Change Cipher Spec、Encrypted Handshake Message**
【Certificate*】客户端证书
如果服务器发送了“Certificate Request”要求校验客户端身份那么客户端需要回应自己的证书。如果客户端没有合适的证书直接抛出告警信息让服务端处理服务端的处理方式通常就是断开TCP连接。和所选密钥套件中密钥交换算法Key Exchange匹配的用于服务器验证客户端身份的X.509证书。
【Client Key Exchange*】客户端密钥交换信息合法性校验通过后客户端计算产生随机数字Pre-master并用证书公钥加密发送给服务器。
对于不同的密钥交换算法,密钥交换信息格式也不同:
| 密钥交换算法 | 密钥交换信息 |
| :------------- | :------------------------ |
| RSA | EncryptedPreMasterSecret |
| Diffie-Hellman | ClientDiffieHellmanPublic |
| Fortezza Kea | FortezzaKeys |
通常我们都会用RSA而RSA的密钥交换信息就是加密的预主密钥Encrypted Pre-Master Secret。服务端会生成48字节的预主密钥用服务器传过来的公钥证书加密该预主密钥。
【Certificate Verify*】客户端证书校验信息
用于提供客户端证书的显示校验信息仅在具有签名功能的客户端证书也就是除包含固定diffie-hellman参数的证书外的所有证书之后发送。它是采用客户端的私钥加密的一段基于已经协商的通信信息得到的数据服务器可以用公钥解密验证。
【Change Cipher Spec】更换加密规约
此时客户端已经获得全部的计算协商密钥所需信息两个明文随机数random_S与random_C还有自己计算产生的Pre-master。
用于提示服务端这条连接以后都使用当前协商好的加密方式以及主密钥,是一条事件消息。
【FinishEncrypted Handshake Message】完成信息
当所有操作完成后发送Finish信息。Finish信息包含了Handshake信息、主密钥的哈希散列如SHA、MD5数据用于验证身份校验和密钥交换过程都成功了。Finish消息不要求收到回包发送之后可以立刻进行加密应用数据传输。
**5、服务端回应客户端**
服务端同样地发送Change Cipher Spec、FinishEncrypted Handshake Message消息然后开始数据传输。
#### **抓包实例讲解**
1、访问[www.jd.com](https://cloud.tencent.com/developer/article/www.jd.com?from_column=20421&from=20421)https网站抓取数据包筛选出tls协议内容。tls && tcp.port==60457
![img](../images/TCPIP/tls-5.png)
2、握手过程详解
1ClientHello
![img](../images/TCPIP/tls-6.png)
客户端TLS 1.2协议、客户端随机数、SessionID、加密套件支持16种、压缩算法null
2ServerHello
![img](../images/TCPIP/tls-7.png)
服务器也用TLS 1.2提供服务器随机数没有找到这个客户端的SessionID所以填入了新的SessionID选择了TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA384加密套件同意不压缩数据
3Server -> Client
- Certificate
- Server Key Exchange
- ServerHello Done
![img](../images/TCPIP/tls-8.png)
回复了crt证书回复了服务器密钥交换信息回复了Server Hello Done
4Client -> Server
- Client Key Exchange
- Change Cipher Spec
- Encrypted Handshake Message
![img](../images/TCPIP/tls-9.png)
客户端校验了证书合法性单向认证于是客户端没有发送证书产生了预主密钥并用服务器发过来的公钥加密放到Client Key Exchange发送给服务器生成主密钥及一系列通信密钥发送Change Cipher Spec通知服务端后面再发送的消息都会使用前面协商出来的秘钥加密了。Encrypted Handshake Message后完成握手。
5Server -> Client包括三部分
- New Session Ticket
- Change Cipher Spec
- Encrypted Handshake Message
![img](../images/TCPIP/tls-10.png)
服务端收到预主密钥取出预主密钥生成主密钥及一系列通信密钥发送Change Cipher Spec、Encrypted Handshake Message后完成握手。
**New Session Ticket**
包含了一个加密通信所需要的信息,这些数据采用一个只有服务器知道的密钥进行加密。目标是消除服务器需要维护每个客户端的会话状态缓存的要求。
**Change Cipher Spec**
编码改变通知。这一步是服务端通知客户端后面再发送的消息都会使用加密,也是一条事件消息。
**Encrypted Handshake Message**
这一步对应的是 Server Finish 消息,服务端也会将握手过程的消息生成摘要再用秘钥加密,这是服务端发出的第一条加密消息。客户端接收后会用秘钥解密,能解出来说明协商的秘钥是一致的。
到这里双方SSL/TLS握手完成。
6Application Data
![img](../images/TCPIP/tls-11.png)
开始加密地传输数据
### **四、TLS与SSL差别**
| 协议 | 使用情况 |
| :----------- | :--------------------------------------------- |
| SSLv3.0以下 | 有安全问题,且已被废弃,不建议使用 |
| TLSv1.0/v1.1 | 过渡版本,不建议使用 |
| TLSv1.2 | 目前绝大多数都在使用,不知道选什么就选这个版本 |
| TLSv1.3 | 最新的更快更安全的协议,如果有条件建议一步到位 |
SSL/TLS由于使用了加密算法非常消耗CPU资源因此应该尽可能将SSL在LB[负载均衡](https://cloud.tencent.com/product/clb?from_column=20065&from=20065)Load Balance层终结掉。终结的意思是[负载均衡器](https://cloud.tencent.com/product/clb?from_column=20065&from=20065)对外提供SSL连接对内提供TCP连接把SSL剥离掉。这样传输更快且后端服务不需要消耗CPU资源处理SSL了后端服务一般都是VPC的肯定安全
**TLS的主要增强内容**
> TLS的主要目标是使SSL更安全并使协议的规范更精确和完善。TLS 在SSL v3.0 的基础上,提供了以下增强内容:
- 1.更安全的MAC算法
- 2.更严密的警报
- 3.“灰色区域”规范的更明确的定义
**TLS对于安全性的改进**
- 1.对于消息认证使用密钥散列法TLS 使用“消息认证代码的密钥散列法”HMAC当记录在开放的网络如因特网上传送时该代码确保记录不会被变更。SSLv3.0还提供键控消息认证但HMAC比SSLv3.0使用的消息认证代码MAC 功能更安全。
- 2.增强的伪随机功能PRFPRF生成密钥数据。在TLS中HMAC定义PRF。PRF使用两种散列算法保证其安全性。如果任一算法暴露了只要第二种算法未暴露则数据仍然是安全的。
- 3.改进的已完成消息验证TLS和SSLv3.0都对两个端点提供已完成的消息该消息认证交换的消息没有被变更。然而TLS将此已完成消息基于PRF和HMAC值之上这也比SSLv3.0更安全。
- 4.一致证书处理与SSLv3.0不同TLS试图指定必须在TLS之间实现交换的证书类型。
- 5.特定警报消息TLS提供更多的特定和附加警报以指示任一会话端点检测到的问题。TLS还对何时应该发送某些警报进行记录。
### **五、SSL/TLS 可以解决什么安全问题**
TLS的基本工作方式是客户端使用非对称加密与服务器进行通信实现身份验证并协商对称加密使用的密钥然后对称加密算法采用协商密钥对信息以及信息摘要进行加密通信不同的节点之间采用的对称密钥不同从而可以保证信息只能通信双方获取。
身份验证通过验证CA证书验证服务器的身份不能造假。
信息加密:通过加密,混淆明文数据,让数据在网络中传输更加安全。
散列算法:由于散列函数不可逆,攻击者无法还原明文,同时无法篡改文件内容。
### **六、HTTPS性能损耗**
前文讨论了HTTPS原理与优势身份验证、信息加密与完整性校验等且未对TCP和HTTP协议做任何修改。但通过增加新协议以实现更安全的通信必然需要付出代价HTTPS协议的性能损耗主要体现如下 1握手延时
一次完整的握手至少需要两端依次来回两次通信至少增加延时2* RTT利用会话缓存从而复用连接延时也至少1* RTT*。 2加解密延时 & CPU资源消耗
除数据传输之外HTTPS通信主要包括对对称加解密、非对称加解密(服务器主要采用私钥解密数据)
网上评测数据参考:
压测 TS8 机型的单核 CPU**对称加密算法AES-CBC-256 吞吐量 600Mbps非对称 RSA 私钥解密200次/s**。不考虑其它软件层面的开销10G 网卡为对称加密需要消耗 CPU 约17核24核CPU最多接入 HTTPS 连接 4800;
**静态节点当前10G 网卡的 TS8 机型的 HTTP 单机接入能力约为10w/s**如果将所有的HTTP连接变为HTTPS连接则明显RSA的解密最先成为瓶颈。因此RSA的解密能力是当前困扰HTTPS接入的主要难题。