前言

在 HTTPS 协议的握手过程中,客户端除了要获取到来自服务端的公钥,还要获取到一个数字证书。公钥是用于加密加密客户端生成的会话密钥返还给服务端,是保证过程的内容隐秘性;而证书则是用于判断当前的内容确实是来自于可信的服务端,即前证明发送方的身份。
image.png
如果数字证书是可信的,那么客户端就会进行之后的握手操作(生成会话密钥返回给服务端……);若不可信,一般的浏览器都会提示你当前网站存在危险,然后让你选择是否继续访问。
image.png
之前仅仅是知道数字证书是用来验证发送方可靠的,今天就来进一步看看这到底是怎么验证的。

服务端配置证书

数字证书是由一种权威机构 Certificate Authority (CA) 所颁发的证书,就好比车管所给我发驾驶证证明我可以开车上路,公安局给我发身份证证明我就是我。网站的开发者向这类机构申请证书然后保存在网站的服务器,这样就可以在 HTTPS 的握手阶段传给客户端了。

首先,网站公司将含有自己身份信息的表单提交给 CA 机构,这些身份信息包括公钥、公司的信息、站点信息等。CA 对这类信息进行审核,若一切顺利,则 CA 对这些明文资料进行 HASH 得到信息摘要,接着用 CA 自己的私钥对摘要进行加密,得到数字签名。接着将数字签名附加在表单上,就变成了数字证书,返回给网站公司。
image.png

客户端验证证书

客户端浏览器在收到证书后,主要关注证书有效期、证书是否被吊销、证书是否是 CA 颁发的、CA 本身是否合法

对于证书的有效期,浏览器直接用当前的时间比对证书上时间即可判断。对于证书是否被吊销,有两种方式进行验证:一是下载证书的吊销列表,通过查表判断;二是在线验证。

对于验证证书是否是 CA 颁发的,类似重复了一遍 CA 颁发证书的流程:

  • 浏览器对证书中的公钥和信息部分进行 HASH 得到信息摘要。
  • 浏览器使用 CA 的公钥,将数字签名解密,得到另一份信息摘要。
  • 比对这两份信息摘要,对,检查内容是否被篡改比对的是内容的哈希值!

image.png
所以,实际上服务端要有两个证书,一个是当前网站的证书,一个是 CA 的证书,这两者要一同发给客户端浏览器。

CA 的合法性

虽然证书是由 CA 颁发,但是 CA 本身可能是恶意的非法机构,所以还需要保证 CA 的合法性。首先 CA 数目众多,所以全部存储起来进行查表验证不切实际,所以 CA 采用树状的结构进行组织,分为根 CA 和中间 CA。根 CA 是经过了严格的验证的,操作系统会内置这些合法的根 CA

所以,总体的验证过程就是,从当前的 CA 沿着数字证书链,一直查找到根 CA,然后比对操作系统维护的根 CA 集合判断合法性。
image.png

数字证书 & 数字签名

这两个概念我个人容易混淆,再进行区分一下:

  • 证书,包含了签名,用于提供发送方的基本信息,如公钥、网站资料
  • 签名,用于验证发送方是否通过 CA 验证;由于签名使用的是非对称加密获得,所以数字签名的另一个作用就是用于判断数字证书是否被篡改

image.png

总结一下

  • 数字证书 = 网站身份信息 + 数字签名
  • 数字签名 = 加密(HASH(网站信息)),也就是对摘要进行加密
  • 客户端如何验证证书?
    • 证书可靠性:服务端传来 CA证书、网站证书,使用 CA 公钥解密数字签名得到网站信息的 HASH;主动将网站信息进行 HASH;两者进行比对
    • CA 的合法性:沿着数字证书链找到根 CA,与操作系统保存的根 CA 集合进行比对