HTTPS 协议原理和流程
HTTPS 是互联网上流行的安全超文本传输协议,它能保证数据传输过程中的保密性和完整性。谷歌、苹果等互联网巨头都在力推 HTTPS,其平台对于传统的 HTTP 展示警告,甚至拒绝接入,国内大型互联网公司也开始启用全站 HTTPS。本文对 HTTPS 相对于 HTTP 差异的 SSL/TLS 的原理和交互流程进行梳理,以便理解 HTTPS 的原理流程。
作者:王克锋
出处:https://kefeng.wang/2018/03/12/https-protocol/
版权:自由转载-非商用-非衍生-保持署名,转载请标明作者和出处。
1 HTTPS 的本质
HTTP
(HyperText Transfer Protocol)是超文本传输协议,它基于 TCP 实现,请求和响应双方都采用约定格式的 Header+Body 进行交互,关于 HTTP 协议的细节本文不再赘述。HTTP 基于明文传输,传输途中存在被监听和篡改的风险;SSL/TLS
(Secure Sockets Layer/Transport Layer Security)是安全传输协议,用于保障所传输数据的保密性和完整性;HTTPS
(Hypertext Transfer Protocol Secure,常称为 HTTP over SSL|TLS)是安全超文本传输协议,是在 TCP 之上进行了加密之后,再基于 HTTP 传输,它是安全的。
可见,SSL/TLS 是在 TCP 之上加了一层加密等处理,不影响原有的 TCP 和 HTTP,上下都是透明的。
2 SSL/TLS 概述
参考资料: 维基百科 - 超文本传输安全协议 (HTTPS)
参考资料: 维基百科 - 传输层安全性协议 (SSL/TLS)
2.1 主要功能
- 防冒充(pretending): 验证交互双方(通常只是对服务端)身份的真实性;
- 防窃听(eavesdropping): 对传输的数据进行加密,即使被截获也无法被识别;
- 防篡改(tampering): 确保接收方收到的数据是原始未篡改过的,若被篡改能识别出来并丢弃;
2.2 SSL 协议
SSL(Secure Sockets Layer)安全套接层协议,由网景公司(Netscape)随着 HTTPS 一并推出。
- SSL 1.0: 于 1994 年设计,但未发布,存在严重的安全漏洞;
- SSL 2.0: 于 1995 年发布,存在数个严重的安全漏洞;
- SSL 3.0: 在 1996 年发布,完全重新设计。IETF 通过 RFC 6101 发表。
2014年10月,Google 在 SSL 3.0 中发现设计缺陷,建议禁用此一协议。
而且,对于低版本的 TLS,攻击者可以向 TLS 发送虚假错误提示,然后将安全连接强行降级到过时且不安全的 SSL 3.0,然后就可以利用其中的设计漏洞窃取敏感信息。
所以,Google/Mozilla/微软都在自己公司相关产品中陆续禁止向后兼容,强制使用 TLS 协议。
2.3 TLS 协议
TLS(Transport Layer Security)传输层安全性协议,由 IETF 基于 SSL 标准化并推出。
- TLS 1.0: 1999 年发布 RFC 2246,与 SSL 3.0 差异非常小,TLS 1.0 允许降级到 SSL 3.0,所以也是不安全的;
- TLS 1.1: 2006 年发布 RFC 4346,提高了安全性;
- TLS 1.2: 2008 年发布 RFC 5246,再次提高了安全性;
- TLS 1.3(草案): 2018 年发布 draft-ietf-tls-tls13-28,再次提高了安全性,是建议标准。
SSL 所有版本、还有 TLS 1.0,都存在漏洞,不要使用;
目前使用广泛的是 TLS 1.1 / TLS 1.2。
TLS 1.3 尚在草案阶段。
3 SSL/TLS 交互过程
这里有个重要依据是RSA公钥加密算法:
- 对于数据交换双方,都拥有自身的公钥和私钥,私钥都为自己私藏,公钥都向对方公开;
- 同样一个数据,发送方使用自身的私钥加密,接收方收到后可以用发送方的公钥解密。
SSL/TLS 交互过程如下图所示:
3.1 双方协商交互参数
客户端发送 ClientHello 消息,组成部分如下:
- 客户端生成的随机数(RNc=Random Number of Client):后面用于生成“会话密钥”
- 支持的 SSL/TLS 协议版本:比如 TLS1.2
- 支持的加密算法: 比如RSA公钥加密
- 支持的压缩算法
服务端响应 ServerHello 消息,组成部分如下:
- 服务端生成的随机数(RNs=Random Number of Server):后面用于生成“会话密钥”
- 确认使用的 SSL/TLS 协议版本:比如 TLS1.2,这是挑选的双方都支持的协议版本,如果没有共同版本,则握手失败
- 确认使用的加密算法: 比如RSA公钥加密
- 确认使用的压缩算法
3.2 双方交换并验证证书
服务端和客户端都可以有证书(客户端证书只出现在对安全性要求极高的情形,比如银行向用户提供的U盾里就包含有客户端证书),以证明自己身份的真实性。
证书包含自己的名称、受信任的证书颁发机构(CA)和自己的公钥,这些证书通常基于 X.509。
证书验证的依据是:双方都预先安装公信的根证书颁发机构证书,可使用它们来验证双方的证书的有效性。
需要注意的是,握手阶段的通信都是明文的。
- 服务端:向客户端发送服务端证书(证书中包含服务端公钥),并向客户端索要客户端证书;
- 客户端:收到服务端证书后,验证其身份有效性(可信机构颁发、域名一致、未过期等),如验证失败则握手失败,如成功则从中取出服务端公钥;
- 客户端:向服务端发送客户端证书(证书中包含客户端公钥);
- 服务端:收到客户端证书后,验证其身份真实性,如验证失败则握手失败。
3.3 双方生成“主密钥”
- 客户端对随机数值(RNc+RNs)作哈希,并用自己的公钥私钥、对方公钥签名,并发送给服务端;
- 服务端以同样算法(自己的公钥私钥、对方公钥),检查客户端发送的哈希签名;
- 客户端生成随机数,称之为“预置主密钥”(PMS=Pre Master Secret),用于“主密钥”的因子。并用客户端私钥加密,再发送给服务端,服务端使用客户端公钥解密取得 PMS,至此双方有相同的 PMS;
- 双方使用一致的算法生成相同的“主密钥”(MS=Master Secret):RNc+RNs+PMS,然后使用自己的公钥和私钥,再加上对方的公钥。
3.4 完成握手并开始交互
双方都使用“主密钥”作为加密和解密的密钥,完成握手。
此后,数据传输的记录层(Record layer)数据可以被随意压缩、加密,对方可以还原为普通的 HTTP 请求,进行交互。