HTTP协议通信过程中使用未经加密的明文,安全性无法得到保证。比如在Web页面中输入信用卡号,如果这条通信线路遭到窃听,那么信用卡号就暴露了。
为了统一解决上述这些问题,需要在HTTP上再加入加密处理和认证等机制。我们把添加了加密及认证机制的HTTP称为HTTPS(HTTP Secure)。
宏观
HTTPS的整个连接过程是相当复杂的,网络、加密等均有涉及,所以我们先从宏观上看一下HTTPS是如何连接的,然后对连接过程中的点进行细化,请看下图
- 客户端和服务器的协商过程,主要用来确定SSL版本、使用的加密算法、秘钥长度等
- 协商过程中,服务端会发送公开秘钥证书给客户端,客户端用认证机关的公开密钥确认证书的有效性,然后取出公开秘钥
- 客户端使用获得到的公开密钥,对客户端生成的通信加密中使用的一种被称为Pre-master secret的随机密码串进行加密,发送给服务端
- 服务端使用私有秘钥对发来的数据进行解密,取出Pre-master secret
- 服务端和客户端根据Pre-master secret生成master_secret,master_secret的计算公式为PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random),其中 ClientHello.random和ServerHello.random在协商过程中服务端和客户端完成交换,再通过该master_secret来产生对称加密的key
- 客户端和服务端使用对称加密的key进行后续数据的发送
细节
SSL和TLS
SSL(Secure Sockets Layer,安全套接字层)协议最初是网景公司为了保障网上交易安全而开发的,该协议通过加密来保护客户个人资料,通过认证和完整性检查来确保交易安全。为达到这个目标,SSL协议在直接位于TCP上一层的应用层被实现。
SSL和TLS有什么关系呢?
IETF后来在标准化SSL协议时,将其改名为Transport Layer Security(TLS,传输层安全)。很多人会混用TLS和SSL,但严格来讲它们并不相同,因为它们指代的协议版本不同。
通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信了。简言之,所谓HTTPS,其实就是身披SSL协议这层外壳的HTTP。
在采用SSL后,HTTP就拥有了HTTPS的加密、证书和完整性保护这些功能。
SSL是独立于HTTP的协议,所以不光是HTTP协议,其他运行在应用层的SMTP和Telnet等协议均可配合SSL协议使用。可以说SSL是当今世界上应用最为广泛的网络安全技术。
TLS在可靠的传输层(TCP)之上运行,这意味着首先必须完成TCP的“三次握手“。
对称加密和非对称加密
对称加密:也叫共享秘钥加密,加密和解密同用一个密钥。服务端将秘钥发送给客户端的过程中,容易被劫持,失去安全效果。
非对称加密:也叫公开秘钥加密,非对称加密有两把秘钥,一把叫做私有密钥(private key),另一把叫做公开密钥(public key)。顾名思义,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得。发送密文的一方使用公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。
HTTPS在交换pre_master_secret的过程中,使用的是非对称加密,主要目的是安全的协商出对称加密秘钥。
HTTPS获取到对称加密秘钥后,使用对称加密算法加密发送出的数据。
认证机关
公开秘钥存在一些问题,客户端如何知道收到的公开密钥确实是服务端的公开秘钥,传输中没有被攻击者替换掉?
这时候就需要数字证书认证机构(CA,Certificate Authority)和颁发的公开密钥证书。
服务器的运营人员向数字证书认证机构提出公开密钥的申请。数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。
服务端将证书发给客户端,客户端用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事:一,认证服务器的公开密钥的是真实有效的数字证书认证机构。二,服务器的公开密钥是值得信赖的。
客户端如何拿到数字证书认证机构的公开密钥?多数浏览器开发商发布版本时,会事先在内部植入常用认证机关的公开密钥。
HTTPS的安全通信流程
了解完宏观和细节,我们来看一下HTTPS完整的通信流程,这个流程是从TCP握手之后开始的
步骤1:客户端通过发送Client Hello报文开始SSL通信。报文中包含客户端支持的SSL的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。
步骤2:服务器可进行SSL通信时,会以Server Hello报文作为应答。和客户端一样,在报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
步骤3:之后服务器发送Certificate报文。报文中包含公开密钥证书。
步骤4:最后服务器发送Server Hello Done报文通知客户端,最初阶段的SSL握手协商部分结束。
步骤5:SSL第一次握手结束之后,客户端以Client Key Exchange报文作为回应。报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串。该报文已用步骤3中的公开密钥进行加密。
步骤6:接着客户端继续发送Change CipherSpec报文。该报文会提示服务器,在此报文之后的通信会采用Pre-master secret密钥加密。
步骤7:客户端发送Finished报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
步骤8:服务器同样发送Change Cipher Spec报文。
步骤9:服务器同样发送Finished报文。
步骤10:服务器和客户端的Finished报文交换完毕之后,SSL连接就算建立完成。当然,通信会受到SSL的保护。从此处开始进行应用层协议的通信,即发送HTTP请求。
步骤11:应用层协议通信,即发送HTTP响应。
步骤12:最后由客户端断开连接。断开连接时,发送close_notify报文。上图做了一些省略,这步之后再发送TCP FIN报文来关闭与TCP的通信。
严肃版的通信流程如下图所示
总结
HTTPS的连接过程还是挺复杂的,本文只是简单的介绍了整个框架,里面还有诸多的细节值得去探讨。至于探讨到什么深度,完全看自己的需要,毕竟对于一些工作,不懂HTTPS也能做。
资料
最后
大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)
我的个人博客为:https://shidawuhen.github.io/
往期文章回顾:
技术
- HTTPS连接过程
- 限流实现2
- 秒杀系统
- 分布式系统与一致性协议
- 微服务之服务框架和注册中心
- Beego框架使用
- 浅谈微服务
- TCP性能优化
- 限流实现1
- Redis实现分布式锁
- Golang源码BUG追查
- 事务原子性、一致性、持久性的实现原理
- CDN请求过程详解
- 常用缓存技巧
- 如何高效对接第三方支付
- Gin框架简洁版
- InnoDB锁与事务简析
- 算法总结
读书笔记
思考