TLS 握手过程

我们来看下 HTTPS TLS 1.2 连接(RSA 握手)的整个过程。
1.png
作为准备工作,网站管理员需要申请并安装 CA 证书到服务端。CA 证书中包含非对称加密的公钥、网站域名等信息,密钥是服务端自己保存的,不会在任何地方公开。

建立 HTTPS 连接的过程,首先是 TCP 握手,然后是 TLS 握手的一系列工作,包括:

  • 客户端告知服务端自己支持的密码套件(比如 TLS_RSA_WITH_AES_256_GCM_SHA384,其中 RSA 是密钥交换的方式,AES_256_GCM 是加密算法,SHA384 是消息验证摘要算法),提供客户端随机数。
  • 服务端应答选择的密码套件,提供服务端随机数。
  • 服务端发送 CA 证书给客户端,客户端验证 CA 证书(后面详细说明)。
  • 客户端生成 PreMasterKey,并使用非对称加密 + 公钥加密 PreMasterKey。
  • 客户端把加密后的 PreMasterKey 传给服务端。
  • 服务端使用非对称加密 + 私钥解密得到 PreMasterKey,并使用 PreMasterKey+ 两个随机数,生成 MasterKey。
  • 客户端也使用 PreMasterKey+ 两个随机数生成 MasterKey。
  • 客户端告知服务端之后将进行加密传输。
  • 客户端使用 MasterKey 配合对称加密算法,进行对称加密测试。
  • 服务端也使用 MasterKey 配合对称加密算法,进行对称加密测试。

接下来,客户端和服务端的所有通信都是加密通信,并且数据通过签名确保无法篡改。你可能会问,客户端怎么验证 CA 证书呢?其实,CA 证书是一个证书链,你可以看一下上图的左边部分:

  • 从服务端拿到的 CA 证书是用户证书,我们需要通过证书中的签发人信息找到上级中间证书,再网上找到根证书。
  • 根证书只有为数不多的权威机构才能生成,一般预置在 OS 中,根本无法伪造。
  • 找到根证书后,提取其公钥来验证中间证书的签名,判断其权威性。
  • 最后再拿到中间证书的公钥,验证用户证书的签名。

这就验证了用户证书的合法性,然后再校验其有效期、域名等信息进一步验证有效性。

总结一下,TLS 通过巧妙的流程和算法搭配解决了传输安全问题:使用对称加密加密数据,使用非对称加密算法确保密钥无法被中间人解密;使用 CA 证书链认证,确保中间人无法伪造自己的证书和公钥。

HTTPS 双向认证的目的

单向认证一般用于 Web 网站,浏览器只需要验证服务端的身份。对于移动端 App,如果我们希望有更高的安全性,可以引入 HTTPS 双向认证,也就是除了客户端验证服务端身份之外,服务端也验证客户端的身份。

单向认证和双向认证的流程区别,主要包括以下三个方面。

  1. 不仅仅服务端需要有 CA 证书,客户端也需要有 CA 证书。
  2. 双向认证的流程中,客户端校验服务端 CA 证书之后,客户端会把自己的 CA 证书发给服务端,然后服务端需要校验客户端 CA 证书的真实性。
  3. 客户端给服务端的消息会使用自己的私钥签名,服务端可以使用客户端 CA 证书中的公钥验签。

这里补充一点,对于移动应用程序考虑到更强的安全性,我们一般也会把服务端的公钥配置在客户端中,这种方式的叫做 SSL Pinning。也就是说由客户端直接校验服务端证书的合法性,而不是通过证书信任链来校验。采用 SSL Pinning,由于客户端绑定了服务端公钥,因此我们无法通过在移动设备上信用根证书实现抓包。不过这种方式的缺点是需要小心服务端 CA 证书过期后续证书注意不要修改公钥。