众所周知,HTTPS可以解决HTTP明文传输过程中的安全性问题,尤其是中间人攻击问题。其最初的全称是HTTP over SSL(或者说 http Security)。其中的SSL是指Secure Sockets Layer,后来SSL被TLS(Transport Layer Security )所取代。今天我们就来总结一下HTTPS的要点
This article is first published in the medium MPP plan. If you are a medium user, please follow me in medium. Thank you very much.
HTTPS 版本
当前人们一般将SSL,TLS这两个协议统称为SSL/TLS协议,但大家日常说SSL的时,默认还是指TLS协议。
TLS 协议在版本上有1.1、1.2、1.3,其中1.2曾经是主流,现在推荐使用改进后的 TLS 1.3,它升级了HandShake和Record协议,会使得通信更加安全和高效。
安全上,TLS 1.3 移除了一些在 TLS 1.2 中被认为是不安全的加密算法,如 RC4、DES、3DES、AES-CBC 和 MD5 等,这样可以减少安全漏洞的风险。
性能上,TLS 1.3 减少了握手过程中的往返次数(RTT),从而加快了连接的建立速度。在最佳情况下,TLS 1.3 只需要一次往返就可以完成握手,同时支持0-RTT扩展,而 TLS 1.2 需要两次或更多。
当然,作为设计精良的互联网协议,TLS 1.3也通过hello握手消息的扩展协议考虑了最大化向前兼容,这点不再赘述。
HTTPS 核心流程
依据不同版本的差异,细节流程会略有不同,不追求严谨细致的情况下,HTTPS工作流程如下。
bytebytego 的这个图非常具有表现力,展示了关键的交互和核心的加密流程。最关键的几步在于如何建立TCP链接,如何通过非对称加密协商获取对称加密的密钥,以及最后通过对称加密进行通信。
HTTPS,准确来说是TLS,设计严密,其中最关键的是Record Layer和几种Protocol,前者是数据承载管道,各种子Protocol都跑在它上面 ,其中的Record是TLS数据收发传输的基本单位,类似TCP的segment,IP的Packet,这也是下面这幅图的含义。
上图中Protocol里最重要的是Handshake协议,针对Client Hello进行抓包后,在Wireshark中体现得会更清晰。
HTTPS SNI 扩展
互联网早期,单机服务器没那么强大,配套的HTTPS比如SSL v2也有设计缺陷。那时有一个假定,认为拥有一个IP的单台服务器只会托管一个域名服务,所以DNS解析以后,直连IP时就能非常确定要使用具体某个域名的证书。但后面云计算、虚拟主机大爆发,以及IPv4中IP的稀缺性,一台服务器托管多个域名的场景无可避免,这时服务器面临无法知道客户端到底想要访问哪个域名的SSL证书的问题,从而导致了HTTPS SNI的出现。
SNI(Server Name Indication)是TLS协议的一个扩展,它允许客户端在握手过程中向服务器发送目标主机名信息。这样,服务器就可以在同一个IP地址上托管多个域名的HTTPS服务,并为每个域名提供正确的证书。
这个问题看似简单,在HTTPS逐渐普及,各互联网服务商走向全站HTTPS化的早期,很多CDN厂商甚至都是不支持SNI的。当然在2024年的今天,无论是Nginx等软件生态,还是各厂商,都已经支持了的。
SNI信息是通过TLS握手协议传输的,抓包示意大概是下面这样子。
具体到实操,可以使用openssl s_client子命令中的-servername选项来指定SNI:
|
|
如果使用OpenSSL Library,也可以使用SSL_set_tlsext_host_name和BIO_set_conn_hostname等函数来在代码中设置。
HTTPS 证书机制
HTTPS通过公钥 体系里的非对称、对称及摘要算法,实现了一系列的加解密、签名、验签等功能,基本实现了安全四大特性:机密性、完整性,身份认证和不可否认。如典型的中间人攻击(Man-in-the-middle attack,MITM),也都有了解决方案。
这里为了解决公钥的信任问题,又引入了证书和信任链机制。证书(Certificate)是由第三方CA(Certificate Authority,证书认证机构)颁发的,本质上是一个文件,通常是.crt、.cer 或 .pem 等扩展名存储。这个文件按照一定的标准(如X.509)编码,包含了公钥、证书持有者信息、颁发机构信息、有效期和数字签名等信息。
有一些世界知名的 CA 机构,比如 DigiCert
、VeriSign
、Entrust
、Let’s Encrypt
等,它们签发的证书分 DV、OV、EV 三种,对应不同的可信程度。但CA自己也有信任问题,小CA的信任靠大CA签名认证,但逐层向上到了链条的最后,就是 Root CA,就只能用“自签名证书”(Self-Signed Certificate)或者“根证书”(Root Certificate)了。
大部分操作系统和浏览器都内置了各大 CA 的根证书,HTTPS通信时会顺着证书链(Certificate Chain)逐层验证到根证书。
HTTPS 软件生态
HTTPS,或是说TLS,生态虽然丰富,但OpenSSL一家独大。它几乎支持所有公开的加密算法和协议,已经成为了事实上的标准,许多应用软件都会使用它作为底层库来实现 TLS 功能,比如著名的 Apache、Nginx 等。
OpenSSL源于SSLeay,其后开枝散叶,形成众多分支,如 Google 的 BoringSSL、OpenBSD 的 LibreSSL。OpenSSL的内容也极其庞杂,可以优先使用openssl命令进行学习,具体可以参考ChatGPT。
HTTPS 加速方案
HTTPS很美好,但美好的事物都有成本。所以关于HTTPS全站铺开后的各种优化,基本上可以写成独立的一篇文章,这里先简单提下。
首先是优化RTT,这个在IO密集型的互联网场景下尤为重要,主要是通过升级协议,如升级HTTP/3,升级TLS 1.3,都可以通过不同原理来优化RTT。其次是优化单步骤性能,如增加TLS加速卡,设置单独的TLS集群或模块等,还有一些TLS session resumption等名词也可以关注。
我以前写过一篇文章分享为什么HTTPS为什么这么慢的文章,有兴趣可以阅读一下。
Why does HTTPS need 7 handshakes and 9 times delay?
参考资料
What’s the difference between HTTP and HTTPS?
how-does-https-work