1. 概述

上一篇博客的最后,我们指出了非对称密钥加密体系中同样存在公钥交换的问题。即在公钥体系中,公钥并不是简单的通过网络就可以交换的,因为这样很容易受到中间人攻击。所以如何安全的交换公钥就成了业界需要解决的问题。

公钥基础设施(Public Key Infrastructure, PKI)技术在解决这个问题上引起了极大的关注,并迅速成为 Internet 上现代安全机制的焦点中心。PKI 不是一个简单的算法或思想,而是需要大量经费、精力和决心才能建立、维护与促进的技术方案。PKI 几乎是所有加密系统的必经之路。

PKI 与非对称密钥加密密切相关,包括消息摘要、数字签名和加密服务。要支持这些服务,最重要的是 PKI 中的数字证书技术

2. 数字证书

2.1. 简介

正如前面所说,公钥交换是个问题。经过大量思考,人们提出了数字证书(digital certificates)的革命性思想。

在概念上,数字证书相当于身份证这样的证件。专家的意思很明显,你不是很难知道另一个人的公钥是什么嘛,那我就把每个人的公钥和其类似于身份证的证件关联在一起,这样就很方便知道该公钥的归属了。

更具体来讲,数字证书其实就是一个计算机文件,就像身份证是一个具体的卡片一样。身份证记录了个人的姓名、性别、出生日期等等信息,而数字证书记录了个人和一个公钥的关联关系

身份证由国家统一批准,那显然数字证书也需要一个各方都信任的机构颁发。假如身份证不是国家颁发而是某个小铺子给你的,你还敢用吗。

前面说过,数字证书记录了用户和对应公钥的关联。因此数字证书里面肯定要有用户名和用户的公钥,除此之外数字证书还有什么呢?不妨随便打开一个 https 的网站,然后点地址栏左边那个小锁的图标,然后点 Certificate ,你就可以看到这个网站的数字证书,例如下面就是我的网站的数字证书页面:

可以看到有很多的信息,例如版本号、序列号、颁发者和使用者等等。那个颁发者到底是谁呢?是哪个阿猫阿狗嘛?下面就来详细看看。

2.2. 证书机构

证书机构(Certification Authority, CA)就是可以签发数字证书的信任机构。而谁又能成为证书机构呢?起码各国政府会确定谁有资格成为证书机构,这样起码保证了证书机构的公信力。通常证书机构是一些著名的组织,例如世界上最著名的证书机构是 VeriSign 与 Entrust 。这些组织一定是大家都信任的,这样他们才有权向个人和组织签发数字证书,使其可以在非对称密钥加密的应用程序中使用这些证书。看上面的图片中,我的网站的数字证书的颁发者是 Encryption Everywhere ,其隶属于著名的机构 DigiCert 。

2.3. 数字证书的具体内容

下来可以看看数字证书的一些具体的内容。数字证书的结构在 Satyam 标准中定义。国际电信联盟于 1988 年推出这个标准,当时其被命名为 X. 509 标准,后来该标准于 1993 年和 1995 年做了两次修订。所以现在最常用的应该是 X. 509V3。可以在上图看到,我的数字证书的版本就是 V3 。下图展示了三个版本的基本情况。

可以看到最开始的版本 1 定义了一些基本内容,而版本 2 多了两个条目,分别是颁发者 ID 和 主体人(使用者)ID,目的是为了处理颁发者和使用者的名字出现重复的情况。版本 3 则新增了很多扩展信息。最后一条是 CA 自己的数字签名,这在每个版本中都有。下表展示了最初的版本 1 中的信息条目。

字段 描述
版本(Version) 标识本数字证书使用的 X. 509 协议版本
证书序号(Certificate Serial Number) CA 为这个数字证书产生的唯一标识
签名算法标识符(Signature Algorithm Identifier) 标识 CA 签名本数字证书时使用的算法
签发者名(Issuer Name) 标识生成并签发本数字证书的 CA 名
有效期(Validity) 包含数字证书的生效时间和过期时间
主体名(Subject Name) 标识本数字证书签发给的实体的名字
主体公钥信息(Subject Public Key Information) 包含主体的公钥以及相关的算法

2.4. 数字证书的申请与生成

现在来说一说 CA 到底是怎么生成数字证书的吧。

第一步是密钥生成,假设我想向 CA 申请一个数字证书,那么当然要先把自己的私钥-公钥对生成好。

第二步是注册,我需要把我的公钥和有关我自己的各种信息发送给 CA 。证书请求的格式已经标准化,称为证书签名请求(Certificate Signing Request, CSR)。这是一个公钥加密标准(Public Key Cryptography Standards, PKCS)。CSR 也被称为 PKCS#10 。

第三步是验证,CA 收到信息后当然要验证我的信息,以保证这些信息可以接受。例如用户是一个组织,CA 可能会检查营业记录、历史文件和信用证明等。如果是个人用户,只需要一些简单的验证即可,例如电子邮箱、电话号码等。然后 CA 还要验证的是,我确实有发送过去的公钥对应的私钥,也就是验证那个公钥的有效性。这一步称为私钥的拥有证明(Proof Of Possession, POP)。具体怎么做呢,有很多办法。例如可以要求用户再发送一份被其签名的证书签名请求,这样 CA 可以尝试用公钥来验证这份被签名的请求,如果验证成功则说明用户确实有对应的私钥。或者 CA 可以用公钥直接把申请好的证书加密,然后发送给用户,这样用户只有确实有私钥才能解开这个证书。

第四步是证书生成,CA 验证完成后用程序生成 X. 509 标准的证书,并将证书发给用户,然后在自己的数据库中存储一份副本。

当然啦,上面说的这些过程是教科书式的,那在现实中一个申请者的视角会是什么样呢?例如我为了给我的网站部署 HTTPS ,必须要给我的网站申请一个数字证书,那我得选一个 CA ,然后去 CA 的网站申请,当然,这是要钱的。其实说了这么多,CA 可不是一个什么慈善机构,其也是商业公司,在帮助构建现代网络的信任体系的同时也会通过收费来平衡自己的支出,而收费的数字证书基本都在 1000 元以上每年,真是够贵的。幸好还有一些不收钱的 CA 哈哈,所以你得找那些仅存的不收钱的 CA 申请证书,登录 CA 的网站后点击对应的申请链接,然后填一些自己的信息例如姓名电话等,过几天你的证书就会申请好啦。

2.5. 验证数字证书

好了,我的数字证书申请好了,在下次别人想和我通信然后请求我的公钥的时候,我就可以直接把我的数字证书发过去。那现在又有了一个问题,别人怎么知道你的证书是有效的呢?前面说了所谓的数字证书其实也就是一个文件,那我完全可以伪造一个数字证书啊,然后里面写上该数字证书被某个权威机构签发。

当然这是做不到的,因为 CA 签发的数字证书一定被 CA 自己签名了。还记得前面讲数字证书的结构的时候,我们说每个版本的 X. 509 标准都有一个重要的信息,就是 CA 自己的签名信息吗。简单来讲,CA 成功生成数字证书后,会对除最后一个字段(CA 自己的签名)外的所有字段计算消息摘要,然后用 CA 自己的私钥将该消息摘要签名并放到最后一个字段中。

这样,当任何一个用户收到这个数字证书的时候,就可以通过这个数字签名来验证该数字证书的有效性。具体来讲,数字证书里面的 签名算法标识符 字段已经记录了 CA 签名时使用的消息摘要算法,然后用户使用同样的消息摘要算法计算一下除了最后一个字段外的所有字段的消息摘要。之后使用 CA 的公钥将最后一个字段的数字签名解开,对比一下两个消息摘要信息,如果相同就说明这个数字证书一定是该 CA 签发的。

这就又又又引出了一个问题,我怎么知道这个数字证书的签发 CA 的公钥呢?我通过数字证书知道一个普通用户或机构的公钥,那类似的,我当然也通过 CA 的数字证书来知道该 CA 的公钥。那问题又来了,CA 自己的数字证书从哪来?这就是下一节的内容。

2.6. 证书信任链

首先明确一个概念,世界上有很多不同的 CA ,他们构成了一个层次结构,如下图:

如图所示,其实我们之前说的那些有名的 CA 比如 DigiCert 等都是根 CA ,这些不同的根 CA 构成了很多这种不同的树结构。而每个根 CA 下面都会有几个二级 CA ,其下又可以有三级 CA ,下面可以继续有四级 CA 等等,这些 CA 类似根 CA 的附属机构,这使得一个 CA 不至于管理全部的数字证书。用户申请证书时可以向最下级的三级 CA 申请,而三级 CA 和二级 CA 的上下级关系表示该三级 CA 的数字证书是由该二级 CA 签发的对应的二级 CA 的证书当然也是由上级的根 CA 签发,这种层次结构被称为信任链(chain of trust)

而最下面,Alice 的数字证书由三级 CA1 签发,而 Bob 的数字证书由三级 CA2 签发。那么就来讨论讨论之前的问题,由于有些混乱,所以用序号分隔。

  1. Alice 将自己的数字证书发给 Bob ,其证书由 CA1 签发,Bob 想要验证这个证书的有效性就要用 CA1 的公钥来验证数字签名,但 Bob 不知道 CA1 的公钥,CA1 的公钥记录在 CA1 自己的数字证书中,所以 Alice 发送自己的数字证书的同时还需要发送 CA1 的数字证书给 Bob ,这样 Bob 才有了 CA1 的公钥,从而可以验证 Alice 的证书的有效性。
  2. 但他又得验证这个 CA1 的数字证书的有效性,CA1 的数字证书由上级的二级 CA 签发,所以 Bob 得知道二级 CA 的公钥来验证三级 CA1 的数字证书的签名。那完了,Bob 继续不知道二级 CA 的公钥,这个公钥记录在该二级 CA 自己的数字证书中,所以,Alice 同样还得把这个二级 CA 的数字证书发给 Bob 。这样 Bob 有了二级 CA 的公钥,就可以验证三级 CA1 的证书的有效性。
  3. 那 Bob 又得验证这个二级 CA 的证书的有效性,二级 CA 的证书由上级的根 CA 签发,所以 Bob 得知道根 CA 的公钥来验证二级 CA 的数字证书的签名。

到这一步就可以停住了,因为 Bob 已经知道了根 CA 的公钥。怎么知道的呢,通过安装根 CA 的证书,即预先把根 CA 的证书存储在电脑里。那问题是我也没请求根 CA 的证书啊,这证书是哪来的?其实,你的操作系统在安装好后就帮你安装了常用根 CA 的证书。全球的根 CA 就那些,那我干脆操作系统就自带这些根 CA 的证书不就完了,这样根 CA 的有效性就由操作系统来保证,Win10 应该不会给你安一个假的根 CA 证书对吧。(这是不是就有点像 DNS 了,DNS 也是这样的分层结构,下面的二级 DNS 服务器那么多,但根 DNS 服务器就那几个,我操作系统自己直接内置了不就完了)。而且那些根 CA 的证书是自签名证书(self-signed certificate),即颁发者和主体都是这个 CA 自己。

这样,根 CA 的证书已经预安装了,所以我们可以成功验证下面的二级 CA 的证书的签名,从而成功验证下面的三级 CA 的证书的签名,从而验证了 Alice 的证书的签名,这就是证书信任链这个词的含义!

在 Win10 中,按下 Win + R 键然后运行 certmgr.msc 来查看系统已经安装的证书列表:

2.7. 证书吊销

如果你的身份证丢失,一般可能需要去公安局报失,这样做通常可以让身份证的功能暂时受限。同样,数字证书可以吊销,那为什么要吊销数字证书呢?可能有下面几个常见原因:

  • 数字证书持有者报告说该证书中指定的公钥对应的私钥被破解了(被盗了)。
  • CA 发现签发数字证书时出错。

这时,数字证书需要被看成无效,为此,要吊销这个证书。通常,就像报失身份证的时候你需要向公安局提供身份信息一样,你也需要向 CA 做证书吊销请求,而 CA 得认证该证书吊销请求再做相应的动作。

假设 Alice 要用 Bob 的证书与 Bob 安全通信,但使用 Bob 的证书之前,Alice 要回答下面两个问题:

  • 这个证书是否属于 Bob?
  • 这个证书是否有效,是否被吊销了?

我们知道,证书信任链可以解决第一个问题,那如何解决第二个问题呢?CA 提供了下图所示的证书吊销状态检查机制:

下面就来分别说一说

证书吊销列表

离线吊销状态检查中最常用的是证书吊销列表(Certificate Revocation List, CRL)。顾名思义,这是一个记录着被吊销证书的信息的列表,每个 CA 签发各自的列表并附上自己的签名,所以很好验证。

所以 Alice 检查 Bob 的证书是否过期时只需要去找到 Bob 的 CA 对应的证书吊销列表,然后查看 Bob 的证书是否在其中即可。

这个证书吊销列表被称为离线吊销状态检查的原因是,其是由 CA 每隔固定时间主动更新的,这个间隔时间可能是几个小时也可能是几天。可以想到随着时间的推移这个列表会越来越大,每次都下载一个新的 CRL 听起来不太友好,所以出现了增量 CRL 的概念,顾名思义,一开始先有一个 CRL 的基础版本,然后每次 CA 只更新新增的吊销证书,这样就可以节省流量。

CRL 的优点是查起来效率很高,因为 CRL 已经下载好了直接查就可以。但缺点是不够实时,例如该证书已经吊销了但是 CA 还没更新 CRL 怎么办,与之对应的是联机吊销状态检查中都是实时查询的。

联机证书状态协议

联机证书状态协议(Online Certificate Status Protocol, OCSP)可以检查某个特定时间的某个特定证书是否被吊销,因此是个联机检查。下面简单的看一下 OCSP 的工作过程。

  1. CA 提供一个服务器,被称为 OCSP 响应器,这个服务器包含最新的证书吊销信息。请求者需要发送特定证书的查询请求(称为 OCSP 请求),已检查该证书是否被吊销。
  2. OCSP 响应器收到查询请求后查询服务器中记载的证书吊销的目录,以判断该证书是否吊销。
  3. 根据查询结果,OCSP 响应器向客户机发送 OCSP 响应。该响应可以有三个结果,即 Good 、Revoked 或 Unknown 。OCSP 相应还包括吊销日期、时间和原因。一般来说,建议只有在 OCSP 响应状态为 Good 时才认为证书有效。

3. 总结

好了,必须具备的知识终于讲完了。可以看到,上边所有的这些,包括数字证书、CA、证书吊销状态等等等等技术,一起构成了我们所说的公钥基础设施 PKI ,当然还有很多没有介绍到的技术。

我们终于解决了证明我是我的这个问题,通过数字签名与数字证书,成功的构建起了架在虚拟的互联网上的信任机制。

Last modification:March 23rd, 2020 at 05:02 pm