浏览器验证SSL数字证书的步骤

浏览器和服务器使用SSL/TLS通信时,双方首先要通过几次握手(Handshake),建立加密信道。简单说来,分为下面3步:

  1. 服务器发送自己的SSL证书;
  2. 浏览器验证服务器SSL证书;
  3. 证书验证成功,双方协商得到对称加密密钥,并交换。双方拿到对称加密密钥后,后续的通信都会用它做对称加密。

本文介绍的重点,在前2步。首先,转载一篇国外博客,讲述浏览器检查证书的过程;其次,会引述两个RFC协议的相关内容;最后,wireshark抓包进行验证。

Browsers and Certificate Validation

原文地址: https://www.ssl.com/article/browsers-and-certificate-validation/

使用DeepL 翻译成中文,如下:

## 证书和X.509格式
证书在各方面都是数字文件,这意味着它们需要遵循一种文件格式来存储信息(如签名、密钥、签发人等)。虽然私有的PKI配置可以为其证书实现任何格式,但公共信任的PKIs(即那些被浏览器信任的PKIs)必须符合RFC 5280,这就要求使用X.509 v3格式。

X.509 v3允许证书包含额外的数据,如使用限制或策略信息,作为扩展,每个扩展都是关键或非关键的。浏览器可以忽略无效的或未被识别的非关键扩展,但它们必须处理和验证所有关键扩展。

## 认证路径和路径处理
憑證機構使用私人密碼匙對所有簽發的證書進行加密簽署。这种签名可以不可撤销地证明证书是由某一特定的核证机 构签发的,而且在签署后没有被修改。

CA通过持有相应公钥的自发证书(称为根)来建立其签名密钥的所有权。憑證機構必須遵守嚴格的控制和審核程序來建立、管理和使用根證書,為了減少暴露,通常會使用根證書來簽發中間證書。这些中间证书可以用来签发客户的证书。
浏览器在出厂时都有一个内置的可信根列表。(这些根是来自通过浏览器严格标准的CA的根。) 为了验证证书,浏览器将获得一个证书序列,每个证书都签署了序列中的下一个证书,将签名CA的根与服务器的证书连接起来。

这个证书序列称为认证路径。路径的根部称为信任锚,服务器的证书称为叶子或终端实体证书。

### 路径的构造
通常情况下,浏览器必须考虑多个认证路径,直到他们能够为给定证书找到一个有效的路径。即使一个路径可能包含的证书可以正确地 "链 "到一个已知的锚,但由于路径长度、域名、证书使用或政策的限制,路径本身可能会被拒绝。

对于浏览器遇到的每一个新证书,构建和评估所有可能的路径都是一个昂贵的过程。浏览器已经实现了各种优化,以减少被拒绝的候选路径的数量,但深入探讨这些细节已经超出了本文的范围。

### 路径验证
候选认证路径构建完成后,浏览器使用证书中包含的信息对其进行验证。如果浏览器能够通过密码学的方式证明,从一个信任锚直接签署的证书开始,每个证书对应的私钥都被用来签发路径中的下一个证书,一直到叶子证书,那么这个路径就是有效的。

## 认证路径验证算法
RFC 5280描述了浏览器验证X.509证书认证路径的标准算法。

基本上,浏览器从信任锚(即根证书)开始,遍历路径中的所有证书,验证每张证书的基本信息和关键扩展。

如果该过程以路径中的最后一张证书结束,没有错误,那么该路径被接受为有效。如果产生错误,则该路径被标记为无效。

### 证书的基本处理
无论是否有任何扩展,浏览器必须始终验证基本的证书信息,如签名或签发人。下面的章节显示了浏览器执行检查的顺序。

1. 浏览器验证证书的完整性
证书上的签名可以用正常的公用钥匙加密法进行验证。如果签名无效,则认为该证书在签发后被修改,因此被拒绝。

2. 浏览器验证证书的有效性:
證書的有效期是指簽署憑證機構保證會維持其狀態資訊的時間間隔。浏览器会拒绝任何有效期在验证检查日期和时间之前或之后开始的证书。

3. 浏览器检查证书的撤销状态。
证书签发后,应该在整个有效期内使用。当然,在各种情况下,证书可能会在自然到期前失效。

这类情况可能包括主体改名或怀疑私钥泄露。在这样的情况下,CA需要撤销相应的证书,而用户也信任CA会通知浏览器其证书的撤销状态。

RFC 5280建议CA使用撤销列表来实现这一目的。

证书废止列表(CRL)
核證機關會定期發出一份經簽署、有時間標記的廢止證書清單,稱為證書廢止清單(CRL)。CRL分布在公开的存储库中,浏览器在验证证书时可以获得并查阅CA的最新CRL。

这种方法的一个缺陷是,撤销的时间粒度仅限于CRL的发布期。只有在所有当前已发布的CRL都被安排更新后,浏览器才会收到撤销的通知。根据签名CA的政策,这可能需要一个小时、一天甚至一周的时间。

在线证书状态协议(OCSP)
还有其他的方法来获取废止状态信息,其中最流行的是在线证书状态协议(OCSP)。

OCSP在标准文档RFC6960中进行了描述,它允许浏览器从在线OCSP服务器(也称为回复者)请求特定证书的撤销状态。如果配置得当,OCSP的即时性更强,而且避免了上面提到的CRL更新延迟问题。此外,OCSP Stapling还能提高性能和速度。

4. 浏览器验证发件人
证书通常与两个实体相关联。

签发人,也就是拥有签名密钥的实体,以及
主体,指的是证书认证的公钥的所有者。
浏览器会检查证书的签发人字段是否与路径中前一个证书的主题字段相同。为了增加安全性,大多数PKI实现也会验证发证者的密钥是否与签署当前证书的密钥相同。(请注意,这对于信任锚来说并不正确,因为根是自发的--即它们具有相同的签发人和主体)。

约束处理
X.509 v3格式允许CA定义约束或限制每个证书如何被验证和作为关键扩展使用。路径中的每张证书都可以施加额外的约束,所有后续证书都必须遵守。

证书约束很少影响普通互联网用户,尽管它们在企业SSL解决方案中相当常见。功能性约束可以达到多种操作目的,但其最重要的用途是缓解已知的安全问题。

5. 浏览器检查名称约束
具有适当名称限制的私有(但公众信任的)中间CA可以为组织提供对证书管理和签发的精细控制。证书可以被限制在一个公司或组织的域名的特定域或域树(即包括子域)。名称限制通常用于从公开信任的CA购买的中间CA证书,以防止中间CA为第三方域(如google.com)签发完全有效的证书。

6. 浏览器检查策略约束
證書政策是由核證機關所發表的法律文件,正式詳述其簽發及管理證書的程序。憑證機構可以根據一項或多項政策簽發證書,而每張證書都有這些政策的連結,以便信賴者在決定信任該證書前,可以評估這些政策。

出于法律和操作上的原因,证书可以对证书的政策进行限制。如果发现证书中包含关键策略约束,浏览器必须在进行之前对其进行验证。(然而,关键策略约束在现实世界中很少遇到,所以本文其余部分将不予考虑)。

7. 浏览器检查基本约束(也就是路径长度)。
X.509 v3格式允许签发人定义证书所能支持的最大路径长度。这提供了对每个证书在认证路径中可以放置多远的控制。这实际上是很重要的--浏览器曾经无视认证路径长度,直到一位研究人员在2009年的一次演讲中演示了他如何利用自己网站的叶子证书为一个大型电子商务网站伪造有效证书。

8. 浏览器验证密钥用途
钥匙用途 "扩展部分说明了证书中钥匙的用途,例如加密、签名、证书签名等。这些用途的例子包括加密、签名、证书签名等。浏览器会拒绝违反其密钥用途限制的证书,例如遇到服务器证书的密钥只用于CRL签名。

9. 浏览器继续处理所有剩余的关键扩展文件
浏览器在处理完上述扩展证书后,会继续验证当前证书指定为关键的所有剩余扩展证书,然后再进入下一个。如果浏览器到达一个路径的叶子证书时没有错误,那么该路径就会被接受为有效。如果产生任何错误,则路径被标记为无效,并且不能建立安全连接。

通过www.DeepL.com/Translator(免费版)翻译

两个重要RFC标准

[RFC 5280] PKI X.509 v3规范 

https://tools.ietf.org/html/rfc5280

其中,section-6 给出了证书validation算法。 第一部分的译文多次提到RFC 5820标准。这个标准定义了X.509格式,并给出了路径验证算法(section-6)。 在此,摘录关键部分:

(a)  for all x in {1, ..., n-1}, the subject of certificate x is
          the issuer of certificate x+1;

(b)  certificate 1 is issued by the trust anchor;

(c)  certificate n is the certificate to be validated (i.e., the
     target certificate); and

(d)  for all x in {1, ..., n}, the certificate was valid at the
          time in question

根据算法,第一个证书由trust anchor签发,下一个证书由这个证书签发……直到最后的叶子节点证书。这样由信任锚长出一个链条,一环扣一环,链条上每个节点都是可信的。

[RFC 5246] TLS 1.2规范

https://tools.ietf.org/html/rfc5246

其中,section-7.4.2 规定,server要向client发送 certificate_list 。服务器不是返回单独的某个证书,而是一个证书列表; 因为单独一个证书,没法形成certifate chain,也就无法完成validation: 这和[RFC 5280] 所述流程吻合。

certificate_list
      This is a sequence (chain) of certificates.  The sender's
      certificate MUST come first in the list.  Each following
      certificate MUST directly certify the one preceding it.  Because
      certificate validation requires that root keys be distributed
      independently, the self-signed certificate that specifies the root
      certificate authority MAY be omitted from the chain, under the
      assumption that the remote end must already possess it in order to
      validate it in any case.

这里指定了证书的顺序,第一个是叶子证书。很好理解,因为重要数据在报文中的位置往往靠前。

抓包看看 

借助wireshark,我们实际操作一番。

打开wireshark, 开始抓包,再访问百度官网(https://www.baidu.com)。抓包细节如下: