证书的全部意义在于表明信任。“我有证书,所以我值得信赖。”关于信任的事情是,它可能会丢失。
证书的完整性取决于私钥的保密性。假设入侵者闯入您的服务器并复制您的私钥文件。入侵者现在可以站起来,权威地声明它们是被渗透的服务器,以及证书的通用名或SAN中列出的任何其他服务器。如果入侵者窃取了CEO的用户证书,入侵者可以作为老板发送电子邮件。应用程序和用户都会相信入侵者。此证书不再可信。
进一步假设你注意到了入侵。您必须通知客户端该证书不再可信。
应用程序无法告诉客户端不信任证书。设置虚假服务器版本的入侵者肯定不会将该信息传递给客户端!这些信息必须来自验证链的更高层。通知CA证书已泄露称为证书吊销(revocation)。
吊销(Revocation)很麻烦。即使所有相关人员都本着诚信的原则行事,也并不总是奏效。一些应用程序故意忽略吊销信息,或者实施自己的吊销系统,无视全球标准。然而,准确理解我们的应用程序如何行为不端是计算职业生涯的重要组成部分,这需要首先理解它们应该如何行为。
吊销证书指示CA通知客户端证书不再可信。吊销的确切机制取决于您如何获得证书。如果你有一些通过CA网站获得的证书,你可能有一个允许你吊销同一证书的web界面。像ACME这样的自动化系统以及专有的CA API都有吊销工具和接口。
在吊销旧证书时,您通常会请求替换证书。替换证书必须具有全新的私钥。在生成替换CSR之前,请确保入侵者已被锁定。找出他们是如何闯入并堵住洞的。这可能意味着需要重新安装系统。否则,入侵者将绑架您的新私钥并愉快地继续进行。请注意,替换证书的费用与原始证书的费用相同,除非CA提供了针对这种可能性的吊销保险。
我在吊销过程中遇到的最大问题是,系统管理员不愿意承认他们的设备被黑客入侵。他们认为这是个人的失败,而不是日常的可能性。世界上最细心的司机偶尔会出车祸。世界上最伟大的剑客偶尔会被打败。有时你做得对,但仍然会失败。如果他们使用的是免费证书,他们可能会毁掉现有的证书并重新开始,而不在乎旧证书已经准备好刺他们了。
更糟糕的是,一些组织没有收集证明发生入侵所需的数据,或者缺乏评估这些数据的专业知识。系统管理员可能不确定是否发生了违规行为。每个系统管理员偶尔都会有一种奇怪的发痒感(weird itchy feeling),觉得有什么事情发生了,也许是入侵,但我们不确定?很难去找你的经理说“嘿,有一些奇怪的事情可能是黑客攻击。”——更难开口说“…所以你需要为所有新证书付费。”
如果您的组织需要昂贵、高度验证的EV或OV证书,入侵也可能触发向监管机构的报告。没有系统管理员想要承担这一责任,尤其是当政府收到一份报告,其中包括“因为Inigo有一种奇怪的感觉,一个黑衣黑客潜伏在网络服务器周围“。
如果您可以廉价地替换已吊销的证书,请通过故意吊销自己的证书来测试吊销过程。您的CA能否快速处理证书吊销和替换?也许他们可以。也许他们不能。你必须知道任何一种方式。同样,您需要测试自己部署更新的证书和私钥的能力。
证书吊销本身很简单。关键在于CA如何与客户端通信吊销信息。已经开发了几种协议来应对这个问题,包括证书吊销列表、在线证书状态协议和OCSP 装订(Stapling)。今天的客户可能会使用其中的任何一个或全部。
CA提供未过期但已吊销证书列表的传统方式是证书吊销列表(Certificate Revocation List —— CRL)。此类CA的根证书包含一个“CRL Endpoint”,其中包含下载最新CRL的链接。客户端第一次联系受TLS保护的网络服务时,会下载当前CRL并检查证书的序列号。如果证书在列表中,客户端会拒绝它。
CRL创建于20世纪90年代,当时证书价格昂贵,CA很少,很少有网站需要加密连接。在那个时代,一位报道互联网的记者买下了 mcdonalds.com
,因为他可以。像许多早期的互联网协议一样,CRL没有扩展性。
考虑证书失效过程。关于有多少证书被吊销的确切数字很难找到,也不可靠,但让我们做出一些可行的假设。当你怀疑自己可能被入侵时,你应该吊销你的证书。假设所有证书中有1%被吊销——应该更高,因为如果你每隔几年至少怀疑一次入侵,你就不会注意到,但我们大多数人都没有注意到,所以让我们选择1%。
每年颁发超过10亿个X.509证书。每个CA的CRL将合并为1000万个条目。有些CA有更多,有些则更少。2015年的一项研究表明,不同CA的CRL大小从51 KB到76 MB不等。如果你坐在千兆连接后面,76 MB可能看起来不多,但如果你从一个不太发达的国家拨入,那将是一场噩梦。在CA端,将CRL分发给数百万客户端需要大量的网络容量。
幸运的是,客户端不需要每次点击都下载整个CRL。CRL可以为其CRL查找定义缓存时间。大多数CRL可以缓存24小时,但并非所有CA都遵循这种做法。将缓存时间加倍会使支持CRL下载所需的带宽和设备减半。
CRL也不定期更新。许多CA每三个小时更新一次CRL。其他人…没有。
总的来说,即使CA及时更新其CRL并设置标准缓存时间,您的客户端在您吊销证书后的27小时内也可能容易受到攻击。
OpenSSL可以解码CRL。获取CA用于签署证书的根证书,并找到CRL端点。从该URL下载CA的CRL,并使用 openssl crl
破解它:
xxxxxxxxxx
$ openssl crl -text -inform DER -noout -in myCA.crl
大多数CA以DER格式分发其CRL以减少带宽需求,但您可能会发现PEM编码的CRL。
随着TLS越来越普遍,CRL越来越臃肿,我们试图改进协议。一些CA已经放弃了CRL,转而支持OCSP。
在线证书状态协议(Online Certificate Status Protocol —— OCSP)试图通过允许客户端通过HTTP接口查询CA的单个证书的状态,而不是下载整个列表,从而不引人注目地提高吊销检查的性能。CA的OCSP响应程序以 good 、 revoked 或 unknown 的方式回答,以及客户端可以缓存此答案多长时间。OCSP响应程序使用HTTP。OCSP响应由CA或中介签名,因此不需要用TLS包装。
如果您试图诊断验证问题并怀疑网络连接,可以使用 openssl x509
和 -ocsp_uri
参数从完整证书链中提取OCSP响应者URI。您必须检查完整的证书链,而不仅仅是最终证书。下面,我检查了脱水生成的本地文件(第7章):
xxxxxxxxxx
$ openssl x509 -noout -ocsp_uri -in fullchain.pem
http://r3.o.lencr.org
您可以使用 s_client -showcerts
查询远程服务器,并将其输入 x509
:
xxxxxxxxxx
$ openssl s_client -showcerts -connect mwl.io:443 | openssl x509 -noout -ocsp_uri
您可以使用OpenSSL的 ocsp
子命令来测试证书的有效性。当您想从验证过程中删除任何外部应用程序时,您可以在故障排除期间执行此操作。给链文件加上 -issuer
选项,给证书加上 -cert
。 -text
标志表示提供人类可读的输出。最后,使用 -url
给出OCSP服务器的URI。下面,我测试了我的一份证书的有效性:
xxxxxxxxxx
$ openssl ocsp -issuer chain.pem -cert cert.pem -text -url http://r3.o.lencr.org
OCSP Request Data:
Version: 1 (0x0)
…
OCSP请求包括各种验证哈希值、序列号和nonce,以防止欺骗。我们关心的部分在后面。
xxxxxxxxxx
OCSP Response Data:
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
…
查询成功,恭喜!经过更多的哈希、证书和协议细节,我们终于得到了我们感兴趣的答案:
xxxxxxxxxx
Cert Status: good
This Update: Jan 22 18:00:00 2021 GMT
Next Update: Jan 29 18:00:00 2021 GMT
…
这个证书仍然有效。然后,我们得到给出响应的时间和响应的到期日期。
OCSP使用的带宽比下载整个CRL少得多。CA必须投入更多的处理能力来响应查询,但考虑到当今的计算机,这是一个公平的交易。但是,OCSP会将客户端信息泄露给CA。如果CA曾经知道客户端正在访问由CA签名的证书,那么CA现在知道该客户端正在访问此特定网站。此外,客户端必须更频繁地查询CA。CA仍然是一个验证瓶颈,存在需要消除的瓶颈。
当OCSP客户端检查证书的有效性时,CA会返回一组信息,客户端可以使用这些信息来验证此证书,不仅是现在,而且是将来。我们在上面的手动OCSP查询中收到的“下一次更新”信息是当前查询的到期日期。服务器可以进行OCSP查询,捕获响应,并将其数字装订(staple)到TLS会话中。传入客户端从CA收到一份数字签名的声明,表示作为TLS协商的一部分,证书尚未被吊销。装订的有效期只有一周左右。每隔几天,服务器必须联系CA并续订装订(renew its staple)。这将检查吊销的工作从客户端转移到服务器。服务器每周进行一次吊销检查,而不是每次客户端联系服务器时都进行一次吊销检查。
可以验证证书和装订的客户端不会联系CA进行验证。并非所有客户端和应用程序都支持装订。所有主流网络浏览器都是这样。
Stapling比原始OCSP或CRL更有效,但必须在应用程序服务器上配置。许多应用程序都内置了对获取和更新OCSP装订的支持。如果在Apache中启用装订,它会联系CA并在没有任何外部干预的情况下更新装订。其他应用程序要求您将装订下载到文件中,然后戳(poke)应用程序以读取文件。
许多应用程序,包括OpenSSL,都可以将OCSP装订下载到文件中。大多数ACME客户端可以下载OCSP主文件,即使他们不管理相关证书。OpenSSL命令非常混乱,我建议使用其他任何命令。
如果您要求,CA可以将证书标记为“必须包含装订,否则无效”。您必须在请求证书时要求CA设置此 Must-Staple 标记。这有效地使证书的到期日期与装订相同。如果装订没有续订,客户将不接受证书。我认为Must-Staple是一种优势,但那些在服务器上经历过装订失败的人强烈反对。在启用之前,请考虑您的故障模式。
吊销检查并不总是有效,原因因应用程序支持、CA支持和开发人员选择而异。
哪些应用程序支持哪些吊销方法?这取决于底层TLS库和应用程序的技术债务(debt)。我使用过一些关键任务应用程序,自从CRL成为标准以来,这些应用程序就没有进行过根本性的更新。
并非所有CA都支持所有吊销方法。一些CA只提供空的CRL,期望他们的客户没有技术债务,并依赖OCSP。一些CA提供OCSP,但不提供主食。过时的应用程序和不规则的CA产品的结合在吊销验证方面留下了空白。
更有趣的吊销检查失败来自应用程序开发人员的选择。假设应用程序无法到达CA执行OCSP检查,但证书以其他方式验证?当无法访问最大的OCSP响应程序时,您的web浏览器是否应该显示错误?严格来说,是的。事实上,用户会抱怨。如果人们为你的应用程序付费,像“亲爱的客户,你的互联网连接是垃圾”这样的回答不会让人满意。许多应用程序声明这是“软故障(soft failure)”,耸耸肩,并允许连接。
作为系统管理员,您必须测试应用程序对无法检查吊销的反应。大多数时候,一个将OCSP响应者的IP地址指向127.0.0.2等虚假地址的主机文件条目就足够了。当真正的机密系统无法验证证书吊销状态时,它们可能需要发生严重故障。检查文件。当你发现行为无法改变时,向开发人员投诉。
TLS存在于许多应用程序中,我们讨论了它们使用的标准吊销方法。然而,最明显的TLS应用程序是web浏览器。Firefox、Chrome和Safari的开发人员已经退回到他们作为浏览器更新的一部分分发的CRL。他们也不使用通用的方法。Chrome使用CRLSets,Firefox使用OneCRL,Safari不给他们的方法命名。
默认情况下,Safari和Chrome不会检查OCSP或OCSP装订。您可以启用这些检查。
您应该知道Chrome的吊销证书处理。Firefox和Safari试图提供完整的吊销列表,而Chrome则提供了一个精心策划的列表。Chrome的CRLSets只包含Chrome团队认为“重要”的网站。管理过程不透明,但人们已经编写了提取列表的工具。当我吊销网站的证书时,我预计Chrome用户永远不会意识到这一点。Chrome也不支持OCSP Must-Staple,目前很明显他们无意这样做,尽管Chromium常见问题解答说这种支持比纯OCSP更好。
没有什么比我写一本关于它的书更能有效地促使应用程序改变其行为了。许多组织提供了故意吊销的网页,您可以使用这些网页来测试组织的浏览器。调用一个类似的网站 https://revoked-rsa-dv.ssl.com/
在Firefox、Chrome和Safari中,比较结果。
如果浏览器部署的一切都很糟糕,那么解决方案是什么?存在两个不完整的现实世界解决方案。
如果你在一个大型组织工作,短期证书可以降低风险。许多金融机构,甚至像我的信用合作社这样小的金融机构,都使用一天内到期的证书。部署短期证书需要自动化。一些云公司可以将这些证书作为其全球负载平衡服务的一部分提供。这种解决方案很昂贵。OCSP Must-Staple模拟了短期证书,但谷歌Chrome已明确选择不支持Must-Staple,并将其拒绝传递给其衍生产品。
另一种方法是基于DNS的命名实体身份验证(DNS**-based Authentication of Named Entities —— DANE)。DANE在DNS中提供X.509证书指纹。然而,确保这些指纹有效需要DNSSEC,许多组织不愿意保护他们的DNS记录。DANE验证主要在电子邮件服务器中实现,但大多数浏览器都支持DANE验证插件。我的书 《DNSSEC Mastery》 讨论了DANE。
现在,让我们尽情地冲击服务器,并检查一些TLS连接。