HTTPS(超文本传输安全协议 本质上是HTTP的安全版本。标准的HTTP协议仅规范了客户端与服务器之间的通信格式,但所有数据传输都是明文的,容易被中间人窃听和篡改。HTTPS通过加密传输数据解决了这一安全问题。
HTTPS可以理解为"HTTP+TLS/SSL"。虽然名称中仍保留"SSL"(安全套接层),但现代HTTPS实际使用的是更先进的TLS(传输层安全)协议。目前最新的版本是TLS/1.3。
协议发展史:
SSL 1.0 → SSL 2.0 → SSL 3.0 → TLS 1.0 → TLS 1.1 → TLS 1.2 → TLS 1.3
如今主流浏览器和服务器都已淘汰不安全的SSL协议,全面支持TLS协议。TLS/1.3在安全性、性能和隐私保护方面都有显著提升。
一、CA证书
虽然,TLS或者SSL加密解决了服务端与客户端之间交流信息被窥探的问题,但是,我们仍无法保证客户在输入域名时输入的是正确域名,比如,我想访问CSDN(www.csdn.net),会不会多输一个字符(www.csdnn.net),这样就可以伪造相似的域名来给客户访问,当客户输错时就进入到了错误的网站,
为了解决这个问题,服务端需要申请SSL证书(现代使用的都是TLS协议,但证书仍然习惯称为"SSL证书",证证书本身不依赖SSL或者TLS,它只是用于身份验证和密钥交换的文件,由于SSL最早使用证书,所以"SSL证书"成了通用称呼)来证明这个域名就是大家熟知的CSDN网站。例如我的浏览器就拿到了这个证书
数字证书包含以下关键信息:
- 颁发对象的基本信息(如域名)
- 网站的公钥
- 颁发机构(CA)的数字签名
- 有效期等元数据
当用户通过HTTPS(默认端口443)访问网站时,浏览器会自动验证服务器提供的证书:
- 检查证书是否由受信任的CA签发
- 验证证书中的域名与实际访问的域名是否匹配
- 确认证书是否在有效期内
通过这套机制,即使用户输入错误的域名,只要该域名没有合法的证书,浏览器就会显示安全警告,有效防止用户误入钓鱼网站。
二、TLS握手过程
TLS/1.2
正常的TCP三次握手是不变的,TCP三次握手如下所示:
但是TLS握手需要更多的步骤,在TCP链接建立以后:
客户端发送
Client Hello
消息- 客户端向服务器发起握手,并告知支持的加密参数。
- 包含内容
- TLS 版本(如 TLS 1.2)。
- 客户端随机数(Client Random)(用于后续密钥计算)。
- 支持的加密套件(Cipher Suites)(如
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
)。 - 支持的压缩算法(现代TLS通常不使用压缩)。
服务端发送
Server Hello
消息- 服务器确认加密参数,并生成服务器随机数。
- 包含内容
- TLS 版本(如 TLS 1.2)。
- 服务端随机数(Sever Random)(用于后续密钥计算)。
- 支持的加密套件(Cipher Suites)(如
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
)。 - 会话 ID(Session ID)(用于会话恢复,可选)。
服务端发送
Certificate
消息- 服务器发送自己的证书,供客户端验证身份。
- 包含内容
- 服务器的 X.509 证书(包含公钥、域名、颁发机构等信息)。
- 证书链(Certificate Chain)(中间CA证书,帮助客户端验证信任链)。
- 客户端需验证
- 检查证书是否过期。
- 检查域名是否匹配(防止钓鱼攻击)。
- 检查颁发机构(CA)是否受信任(如 DigiCert、Let’s Encrypt)。
服务端发送
Server Key Exchange
消息
- 如果使用 ECDHE 或 DHE 等密钥交换算法,服务器会发送临时公钥。
- 包含内容
- DH/ECDH 参数(如椭圆曲线名称、临时公钥)。
- 签名(证明参数未被篡改)。
- 服务端发送
Server Hello Done
消息- 告知客户端服务器握手信息发送完毕,等待客户端响应。
- 客户端发送
Client Key Exchange
消息- 客户端生成 预主密钥(Pre-Master Secret) 并加密发送给服务器。
- 包含内容
- 加密的预主密钥(使用服务器证书中的公钥加密,或者用第4步发送的临时公钥进行加密)
- 如果是 RSA 密钥交换,直接发送加密的预主密钥。
- 如果是 ECDHE/DHE,客户端也发送自己的临时公钥。
- 服务端和客户端发送
Change Cipher Spec
以及Finished
消息- 通知服务器,后续通信将使用协商的密钥加密。
- 后续通信使用双方沟通好的秘钥进行通信,即对称加密,秘钥为(客户端随机数 + 服务端随机数 + 预主秘钥)
TLS/1.3
TLS/1.3 的整个握手过程发生了一些改变
- 合并消息:
Server Hello
、Certificate
、Server Key Exchange
合并为一条响应。 - 删除冗余步骤:移除
Change Cipher Spec
(加密切换隐含在握手逻辑中)。
总结
1.2协议的过程
1.3协议的过程
三、TLS/1.3 升级了什么
前向保密
TSL 1.2 中的加密措施主要是 RSA 和 DH 算法,DH算法可以每次都使用新的随机数,因此不存在前向保密的问题,即使从以往的信息中破解出了私钥,那也只是那一次通信的私钥,而RSA存在前向保密问题,因为其私钥和公钥都是静态的,那么一旦私钥被破解,以前通信的消息都会被破解。 其实不使用临时随机数的DH算法也有这个问题。因此静态的RSA和DH秘钥交换算法在TLS/1.3中被移除了。
- TLS/1.2:支持非前向安全的 RSA 密钥交换。
- TLS/1.3:强制使用 ECDHE,即使私钥泄露,历史会话也无法解密。
参数组合
那是不是使用非静态参数就安全了?其实这就相当于我们选择不改密码和经常改密码,经常改密码当然是更加安全的。但实际上一些主机并不支持新版本的TLS,甚至只支持SSL。TLS/1.2 协议是支持版本降级的,因此在这些较旧的主机上必须通过版本降级来通信。
同时,DH算法参数(P与G)是通过服务器来选择的,可以有很多选择,虽然DH算法破解难度大,但是DH并不是所有参数都安全。
TLS/1.2 协议在创建连接时是明文的,因此可能被黑客截获,截获后可以给服务端发送假的 Clien Hello
消息,造成服务端协议降级。虽然1024bit的DH协议很安全,那降级成512bit破解难度就降低不少了。
因此TLS/1.3干脆放弃了DH算法中很多弱参数选择,并对参数进行了限制。
密码套件
TLS/1.2 支持的密码套件有:
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
TLS_PSK_WITH_AES_256_GCM_SHA384
TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
其格式为
TLS_[密钥交换算法]_[身份验证算法]_WITH_[加密算法]_[哈希算法]
这仅是常见的密码套件组合,其实际可选用的密码套件组合更多,所以在建立加密通信之前必须协商需要使用的密码套件组合。
在TLS/1.3 协议中,仅建议五种密码套件:
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_CCM_SHA256
TLS_AES_128_CCM_8_SHA256
密码套件的格式变为
TLS_[对称加密算法]_[哈希算法]
看起来就更简单了,代价是只支持三种密钥交换方式 (EC)DHE
,PSK-only
,PSK ith (EC)DHE
TLS/1.3 中参数就少了很多,速度也快了很多。也正是因为客户端一开始就可以发送协商参数,因此TLS/1.3 相较于 TLS/1.2 少了 1-RTT
恢复会话 (0-RTT)
客户端和服务端此前已完成完整握手,并缓存了会话密钥。 客户端 → 服务端 Client Hello
+ 0-RTT 数据 就可以直接恢复之前的会话。
但这个技术存在一定问题,给了黑客一定的可乘之机,黑客可以截获客户端恢复会话的消息,在多次发送给服务端,那么原本只转账1元,现在就转了n元。
对比
特性 | TLS/1.2 | TLS/1.3 |
---|---|---|
握手耗时 | 2-RTT | 1-RTT(默认),0-RTT(可选) |
密钥交换 | 支持 RSA(不安全)、ECDHE | 仅 ECDHE(强制前向安全) |
加密算法 | AES-CBC、RC4(不安全) | 仅 AES-GCM、ChaCha20 |
握手消息加密 | 仅 Finished 后加密 |
除 Hello 外全部加密 |
降级攻击防护 | 较弱 | 强制版本确认 |
四、好像并不需要CA…吗?
上述的Https握手阶段我们可以发现,似乎可以跳过CA这个过程,但并非如此,这样的话无法解决中间人的问题
客户端在通信时一直在于中间人通信,中间人在截获消息后再发送给服务端。核心在于,在TLS握手阶段,中间人劫持了流量,伪装成了服务端,客户端认为自己与服务端建立了加密通信,但是其实是与中间人建立了加密通信,那加了个寂寞。
所以CA还是需要的,这样一开始你不需要与服务端建立通信,而是与CA建立通信,CA将服务端的公钥保存起来,当你需要的时候再一同生成CA证书发给你,但是…我怎么确定CA是真的呢???
确定CA证书为真就需要数字签名,CA会将网站的各种信息包括网站的公钥整合成CA证书,并通过自己的私钥对证书的哈希值进行加密生成数字签名,数字签名也在这个CA证书中,CA证书部署在服务端的服务器中,好的,那么我们客户端在拿到这个CA证书时就可以通过公钥来解密,并与证书的哈希值对比,相同的话,就是原网站,不同就是被劫持。但是这个CA的公钥,它在CA的服务器上啊,我怎么确定这个CA不是中间人伪造的,这很有可能啊,这就需要再给这个CA机构的网站加一个证书…麻了,没完了。
最终极的解决方案是证书链,或者可以认为是一个树,他有个根,服务端的证书由中间CA机构发,中间CA机构的证书由根CA发,根CA已经无法验证了,那么就直接内置在用户的设备中,操作系统和浏览器都预置了全球可信根CA的证书(含公钥)。
总结来讲:
HTTPS通过 数字证书链 和 预置信任锚 解决这个问题:
- 证书签发流程
- 网站向CA提交信息(域名、公钥等)。
- CA验证网站身份后,用自己的私钥对网站信息(含公钥)签名,生成数字证书。
- 网站将证书部署到服务器。
- 客户端验证流程
- 客户端收到证书后,用CA的公钥验证签名,确认证书未被篡改。
- 进一步验证证书中的域名是否匹配、有效期是否合法。
- 信任锚:预置根证书
- 操作系统和浏览器预置了全球可信根CA的证书(含公钥)。
- 这些根证书是信任链的起点(如微软、苹果、Mozilla维护的根证书列表)。
- 若中间人伪造CA证书,由于客户端未预置其根证书,验证会失败。
五、Https的核心优势
数据加密传输
- 采用 TLS/SSL 协议对通信内容进行端到端加密
- 有效防止中间人攻击(MITM)、流量劫持等安全威胁
- 保护用户敏感信息(如密码、支付信息、个人隐私数据)
身份真实性验证
- 通过 CA 颁发的数字证书验证网站真实身份
- 防止钓鱼网站和域名仿冒(如将 taobao.com 仿冒为 taoba0.com)
- 浏览器会明确展示网站认证信息(地址栏锁形图标)
数据完整性保护
使用消息认证码(MAC)确保传输内容不被篡改
防止运营商劫持插入广告等行为
有效防止中间人攻击(MITM)、流量劫持等安全威胁
保护用户敏感信息(如密码、支付信息、个人隐私数据)