理解 HTTPS

简介

HTTPS 中的 S 代表 Secure,所以 HTTPS 自然就是更安全的 HTTP 的意思。互联网诞生之初 SSL(Secure Sockets Layer 安全套接层)是由 Netscape 这家最早的浏览器公司设计的,主要是用于 Web 的安全传输的协议,这种协议在早期 Web 上获得了广泛的应用。后来被 IETF 标准化形成了 TLS(Transport Layer Security 传输层安全)标准,其历史如下:

  • 1994: SSL1.0,因为存在严重的安全漏洞,未发布。
  • 1995: SSL2.0,这个版本由于设计缺陷,很快被发现有严重漏洞,被废弃。
  • 1996: SSL3.0,重新设计并开始流行,SSL 前三个版本都是由 Netscape 设计实现,有已知漏洞,建议弃用。
  • 1999: TLS1.0,IETF 将 SSL 标准化,即 RFC 2246,也存在部分安全漏洞,比如 RC4 和 BEAST 攻击。
  • 2006: TLS1.1,作为 RFC 4346 发布。
  • 2008: TLS1.2,作为 RFC 5246 发布 。
  • 2015: TLS1.3,尚在制定中,处于草案阶段。

如上,现在互联网世界使用最广泛的应该是 TLS1.2 标准。

目标

SSL/TLS 最初的设计目标就是为了实现下面三个目的:

  1. 保密:第三方无法窃听。
  2. 完整:无法篡改。
  3. 认证:防止身份冒充。

结构

整个互联网构建于 TCP/IP 协议栈基础之上,SSL/TLS 协议处于该分层协议栈结构中的会话层位置:

流程和步骤

1. 客户端发起 HTTPS 请求

客户端向服务端传送:

  • SSL Version : 自己支持的最高协议版本,比如 TLS 1.2
  • Ciphers : 支持的加密套件,比如: RSA 非对称加密算法,AES 对称加密算法
  • 随机数 RandomA

2. 服务端的配置

服务器的数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。

这套证书其实就是一对公钥和私钥。可以想象成一把钥匙和一个锁头,全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。

关于数字证书可以查看另一篇:数字签名是什么?

关于 TLS 算法

TLS 的命名规范:

ECDHE-ECDSA-AES256-GCM-SHA384

基本格式就是密钥交换算法 - 签名算法 - 对称加密算法 - 分组模式(可选) - 摘要算法组成的一个密码串,使用 ECDHE 进行密钥交换,使用 ECDSA 进行签名和认证,然后使用 AES 作为对称加密算法,密钥的长度是 256 位,使用 GCM 作为分组模式,最后使用 SHA384 作为摘要算法。

TLS 里面有比较多的加密算法可供使用,比如 DES、3DES、AES、ChaCha20、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK 等。目前最常用的是 AES-128, AES-192、AES-256 和 ChaCha20。

  • DES 的全称是 Data Encryption Standard (数据加密标准) ,它是用于数字数据加密的对称密钥算法。尽管其 56 位的短密钥长度使它对于现代应用程序来说太不安全了,但它在加密技术的发展中具有很大的影响力。
  • 3DES 是从原始数据加密标准 DES 衍生过来的加密算法,它在 90 年代后变得很重要,但是后面由于更加高级的算法出现,3DES 变得不再重要。
  • AES-128/192/256 都属于 AES,AES 的全称是 Advanced Encryption Standard (高级加密标准),它是 DES 算法的替代者,安全强度很高,性能也很好,是应用最广泛的对称加密算法。
  • ChaCha20 是 Google 设计的另一种加密算法,密钥长度固定为 256 位,纯软件运行性能要超过 AES,曾经在移动客户端上比较流行,但 ARMv8 之后也加入了 AES 硬件优化,所以现在不再具有明显的优势,但仍然算得上是一个不错算法。

3. 传送证书

服务端向客户端传送证书,包含以下信息:

  • 服务器公钥(明文)
  • 申请者的组织信息和个人信息
  • 签发机构 CA 的信息
  • 有效时间、证书序列号等信息(明文)
  • 发行者的数字签名:使用散列函数计算公开的明文信息的摘要,然后用 CA 的私钥对信息摘要进行加密,密文即签名

同时会一并做传送以下信息:

  • 确认使用的 SSL 协议的版本号
  • 加密套件 Cipher Suite
  • 随机数 RandomB
  • CertificateRequest 可选,Server 端需要认证 Client 端身份的请求时发送。 比如,银行提供的各类 U 盾,其实就是一种 Client 证书,一般在线使用专业版网银时才需要。
  • ServerHelloDone 表示 Server 响应结束。

4. 客户端验证证书

客户端的 TLS 来验证证书的合法性:

  • 证书是否过期
  • 签发机构 CA 是否可靠
  • 签发机构 CA 的公钥来验证服务器证书的发行者数字签名
  • 证书上的域名和服务器的实际域名是否一致

如果证书没有问题,那么就生成一个随机数 RandomC。然后把三个随机数 A+B+C 拼接成一个新的随机数 RandomD,用服务端公钥(证书里解析得来)对 RandomD 进行加密,形成行动暗号

如果发现异常,浏览器则会弹出一个警告框提示证书不安全。如果这时用户仍然选择「继续」,就表示不验证证书合法性,直接把证书里的 服务端公钥 拿来用就是了。

5. 传送暗号

客户端把行动暗号发送给服务端,以后两边的通信就通过这个暗号来进行对称加、解密了。

同时向服务端传送以下信息:

  • Certificate 如果在 ServerHello 时服务端要求客户端 U 盾验证,那么 Client 端也会在这一步响应 Server 的 CertificateRequest 请求。
  • CertificateVerify 用于对客户端 U 盾证书提供证明,对于特定的证书需要可选发送。
  • ChangeCipherSpec 告知 Server、Client 已经切换到之前协商好的加密套件(Cipher Suite)的状态,准备加密数据并传输了。
  • ClientFinished Client 会用协商好的算法先加密一小段 Finished 的数据传送给 Server,为了在正式传输前做最后验证。

6. 服务端获取暗号

服务端用自己的私钥解密得到了客户端传过来的行动暗号。同时服务端回应以下信息:

  • NewSessionTicket 表示新建了一个会话票据,传递给 Client。若连接意外中断 Client 需要重建会话时,可以复用该票据,加速握手过程。
  • ChangeCipherSpec 告知 Client,Server 已经切换到协商过的加密套件状态,准备加密数据并传输了。
  • ServerFinished Server 会用协商好的算法加密一小段 Finished 的数据传送给 Client,为了在正式传输前做最后验证。

至此,整个 SSL 握手阶段全部结束。接下来 Client 和 Server 进入使用会话密钥的加密通信过程。

7. 服务端返回加密信息

服务端用行动暗号把数据加密后发回给客户端。

8. 客户端解密信息

客户端用行动暗号解密服务端发过来的信息。

完成!

FAQ

Q: 应用层数据为什么不用非对称加解密?性能开销太大,无法承受。

A: CPU 计算资源消耗非常大。一次完全 TLS 握手,密钥交换时的非对称解密计算量占整个握手过程的 90% 以上。而对称加密的计算量只相当于非对称加密的 0.1%。 非对称加密算法对加密内容的长度有限制,不能超过公钥长度。比如现在常用的公钥长度是 2048 位,意味着待加密内容不能超过 256 个字节。

所以公钥加密目前只能用来作密钥交换或者内容签名,不适合用来做应用层传输内容的加解密。

Q: 交互过程中到底有几个随机数?

A: 一共有三个随机数。

  • 第1个 RandomA 由 clientHello 时生成发送给服务端
  • 第2个 RandomB 由 serverHello 时生成发送给客户端(随着 CA 证书一起发回)
  • 第3个 RandomC=PreMaster 由客户端生成

根据三个随机数,计算得到行动暗号

PreMasterSecret = crypt(RandomA, RandomB, RandomC)

至于为什么要用三个随机数,是为了增加更多随机因素,防止被猜出。

参考文章: