分享

HTTPS证书吊销机制已坏,是时候需要一些新工具了!

 rocky_gan 2017-07-04


Certificate Transparency和OCSP Must-Staple未能足够快地落实起来。



这篇文章最初发表在Scott Helme的个人博客上。


眼下我们在互联网上有个小问题,但我觉得这会逐渐成为更严重的问题:越来越多的网站在获得证书(部署HTTPS所需的至关重要的文件),但是一旦证书方面出了岔子,我们无法保护自己。


证书


随着越来越多的网站部署HTTPS,我们目前看到互联网证书迎来了一股热潮。除了HTTPS在安全和隐私方面明显具有优势外,还有好多原因促使你想要考虑改用这种安全的连接协议,我在文章《仍认为你不需要HTTPS?》(https:///still-think-you-dont-need-https/)中概述了这些原因。这种安全证书通常被称为“SSL证书”或“HTTPS证书”,更广泛的互联网用户正以我们之前在互联网发展史上从未见过的速度获得它们。我每天搜索前100万个网站,分析其安全性的方方面面,每6个月就发布一份报告。你可以在这里(https:///tag/crawl/)查看报告,不过眼下关注的主要结果是HTTPS的采用。


前100万个网站中使用HTTPS的百分比


我们不仅在继续部署HTTPS,部署的速度也在加快。这才是真正取得的进展。获得证书的过程逐渐变得越来越简单,现在归功于出色的Let's Encrypt,还能免费获得证书。简而言之,我们向证书管理机构(CA)发送证书签名请求(CSR),CA会质询我们,证明我们是该域的所有者。这常常通过设置DNS TXT记录或将质询码托管在我们域的随机路径上的某个地方来完成。一旦成功通过这个质询,CA会颁发证书,然后我们可以将它出示给访客的浏览器,在地址栏中获得绿色挂锁和“HTTPS”。


获得证书的过程


我写了几个教程帮助大家了解这个过程,包括如何入手、如何设置智能更新机制以及如何使用双证书。所以这很好。有什么问题吗?


问题在于,如果证书方面出了岔子,你就要遭殃了。


“我们已经被黑!


根本没人想听到这句话,但残酷的现实是,我们确实听到,而且司空见惯。一旦黑客能访问我们的服务器,就可以找许多目标下手,他们能访问的对象之一常常就是我们的私钥。我们用于HTTPS的证书是公共文档――我们将它们发送给连接到我们网站的任何人,但如果使用我们证书的其他人没有我们的私钥,就访问不了。浏览器与网站建立一条安全连接后,会检查服务器拥有它所要使用的那个证书的私钥,这就是为什么只有我们才能使用自己的证书,别人用不了。不过,要是攻击者得到了我们的私钥,情况不一样了。


服务器泄密后,我们的私钥落到攻击者的手里


鉴于攻击者已设法获得了我们的私钥,他们可以使用我们的证书证明他们就是我们。再说一遍:如果你的钥匙失窃,那意味着别人在互联网上可以证明他们就是你。这个问题很严重;在你认为“这永远不会发生在我身上”之前,应该记得Heartbleed。OpenSSL库中的这个小漏洞让攻击者得以窃取私钥,就算你根本没有做错什么,它照样到处肆虐。除此之外,私钥还会以无数的方式因意外或疏忽而泄露。一个简单的事实是,我们可能丢失私钥;若出现这种情况,我们需要有法子来阻止攻击者使用我们的证书。我们需要吊销证书。


吊销证书


万一中招,我们吊销证书,那样攻击者无法滥用证书。一旦证书被标记为“已吊销”,Web浏览器就知道不信任该证书,哪怕证书是有效的。所有者要求吊销证书后,客户不应该接受该证书。


请求吊销证书


一旦我们知道自己已中招,要联系CA,要求对方吊销我们的证书。我们要证明自己是该证书的所有者;一旦我们证明了这点,CA将把该证书标记为已吊销。由于证书已被吊销,我们需要一种方法将该吊销信息通知给可能需要该信息的任何客户。吊销后,访客的浏览器并不立即知道――当然,这是个问题。我们可以使用两种机制来提供该信息:证书吊销列表(CRL)或在线证书状态协议(OCSP)。


证书吊销列表


CRL其实是个很简单的概念,它就是一份列表,列出了CA标记为已吊销的所有证书。客户可以联系CRL服务器,下载一份列表。有了这份列表,浏览器可以检查:向它出示的证书是否在该列表中。如果证书在列表中,浏览器现在知道证书是坏的,不该信任它。浏览器应该会弹出错误信息,放弃连接。如果证书不在列表中,那么一切都很好,浏览器可以继续连接。


下载CRL


CRL的问题在于,它们含有来自负责维护的某个CA的许多吊销证书。因不了解太多细节,它们被CA拥有的每个中间证书搞坏,CA可能将列表分解更小的块。不管列表如何分解,我想要表明的意思仍然一样:CRL通常很庞大。另一个问题是,如果客户没有一份新的CRL,必须在最初连接到你网站时获取一份,这可能会让你网站加载看起来比实际上慢得多。


这听起来不是特别好,那我们不妨来看看OCSP如何?


在线证书状态协议


OCSP提供了一种好得多的办法来解决该问题,与CRL方法相比具有显著优势。使用OCSP,我们向CA询问某一个证书的状态。这意味着CA要做的就是回应证书是好的/已吊销的答案,这比CRL小得多。不赖!


获取OCSP响应


没错,OCSP在性能方面比获取CRL具有显著优势,但是这个性能优势有其代价。这也是相当大的代价:你的隐私。


如果我们考虑一下OCSP请求的是什么(请求一个非常特殊的证书的状态),你可能会开始意识到泄漏了一些信息。如果你发送OCSP请求,基本上是向CA问这个:


 “pornhub.com的证书是否有效?”


所以,这根本不是一种理想的场景。现在你将自己的浏览记录内容通告给了你甚至一无所知的某个第三方,这完全以HTTPS的名义――而HTTPS原本旨在为我们加强安全和隐私。这是不是颇具讽刺意味?


硬失效


不过等等:还有别的方面。我在上面谈论了CRL和OCSP响应,这是浏览器可以用来检查证书是否被吊销的两种机制。它们看起来就像这样。


CRL和OCSP检查


浏览器一收到证书,就会联系这其中一个服务,并执行必要的查询,最终确定证书的状态。但是如果你的CA遭遇不幸、基础设施宕机,将会怎样?如果看起来像下面这种情况,将会怎样?


CRL和OCSP服务器宕机


这时候,浏览器只有两个选择。它可以拒绝接受证书,因为它无法检查吊销状态,或者在不知道吊销状态的情况下冒险接受证书。这两个选择各有优缺点。如果浏览器拒绝接受证书,那么每当你的CA遭遇不幸、基础设施又宕机,你的网站也会跟着宕机。如果浏览器继续接受证书,那么它就面临使用可能被盗的证书这个风险,因而将用户暴露于相关风险。


这是个艰难的选择――不过现在,这任何一种情况没有实际发生。


软失效


如今实际发生的是,浏览器会做我们所说的“软失效吊销检查”(soft fail revocation check)。也就是说,浏览器会试着检查证书吊销,但是如果响应没有返回,或者没有在短时间内返回,浏览器会完全不理。更糟糕的是,Chrome甚至根本不执行吊销检查。


是的,你没有看错,Chrome甚至不试着检查它遇到的证书的吊销状态。你可能觉得更奇怪的是,我完全认同Chrome的做法;我很高兴地说,Firefox看起来很快也会加入这个行列。


不妨听我细细道来。我们在硬失效方面遇到的问题很明显:如果CA遭殃,我们也跟着遭殃。这就是为何我们提到了软失效。浏览器现在试着执行吊销检查,但如果花太长时间,或者CA似乎宕机,它最终会放弃检查。


等等,如果“CA似乎宕机?”,就会放弃吊销检查。我在想攻击者会不会模仿这个?


攻击者阻止吊销检查


如果攻击者对你执行中间人攻击(MITM),他们只要阻止吊销请求,让人觉得好像CA宕机。然后浏览器会对检查进行软失效处理,继续开心地使用已吊销的证书。每当你浏览并遇到该证书,又没有受到攻击,你都要承受这笔开销:执行吊销检查,查明证书没有被吊销。


谷歌的亚当·兰利(Adam Langley)对吊销性质作了最生动的描述:它好比是安全带,车辆碰撞后迅速发挥保护作用。他说的没错。你每天钻进汽车,系上安全带,让你觉得貌似很安全。后来有一天,出现了状况――你撞车了,从挡风玻璃钻了出来。就在你需要它的时候,它却让你失望。


解决问题


眼下,没有一种可靠的方法来解决这个问题。吊销机制是坏的。不过有几种机制值得一提,将来我们会有一种可靠的吊销检查机制。


专有机制


如果网站中招,攻击者拿到了私钥,他们会冒充该网站,大搞破坏。这可不妙,但结果可能更糟。如果CA中招,攻击者获取了中间证书的签名私钥,会怎样?这将是一场灾难,因为攻击者随后只要给自己的证书签名,就可以冒充他们想要冒充的任何网站。Chrome和Firefox都有各自的机制(其工作原理一样),而不是对中间证书的吊销执行在线检查。


CRLsets和OneCRL


Chrome将其机制称为CRLsets,Firefox将其机制称为OneCRL,它们通过合并可用的CRL,从中选择需要加入的证书来管理吊销证书列表。所以,我们包括了像中间证书这样的高价值证书。


OCSP Must-Staple


为了解释“OCSP Must-Staple”是什么,我们先需要大致介绍OCSP封套(OCSP stapling)的背景。我不会作太多的介绍,可以去我的博客了解OCST封套(https:///ocsp-stapling-speeding-up-ssl/),不过核心内容是:OCSP封套提供了OCSP响应以及证书,让浏览器没必要执行OCSP请求。它之所以被称为“OCSP封套”,是由于其想法是,服务器会“封套”OCSP对证书的响应,并将两者一并提供。


OCSP封套的实际运作


乍一看,这似乎有点奇怪,因为服务器几乎将其自己的证书“自我认证”为未吊销,但它都能检查出来。OCSP响应仅在短时间内有效,由CA签名,签名方式与签名证书的方式一样。因此,正如浏览器可以验证证书绝对来自CA,它也可以验证OCSP响应来自CA。这解决了OCSP重大的隐私问题,还消除了客户要执行这个外部请求的负担。完胜!


不好意思,但实际上并不那么好。OCSP封套是很好,我们在自己的网站上都应该支持它,但是坦率地说我们认为攻击者会启用OCSP封套吗?不,他们当然不会。我们需要一种方法迫使服务器进行OCSP封套,这就是OCSP Must-Staple的用途。我们向CA请求证书时,要求对方在证书中设置OCSP Must-Staple标志。这个标志告诉浏览器:证书在提供时必须附有OCSP封套,否则将被拒绝。设置标志很容易。


CSR中的OCSP must-staple


鉴于我们有了该标志已设置的证书,我们(主机)必须确保我们采用OCSP封套,否则浏览器不接受我们的证书。万一中招、攻击者获得我们的密钥,他们在使用我们的证书时还要提供OCSP封套。如果他们不附上OCSP封套,浏览器将拒绝证书。如果他们果真附有OCSP封套,那么OCSP响应会说证书已吊销,浏览器将拒绝。哇哦!


攻击者企图使用must-staple证书


OCSP Expect-Staple


虽然Must-Staple听起来是解决吊销问题的好办法,它其实还没有到位。我发现最大的问题之一是,作为网站运营者,我实际上不知道OCSP封套有多可靠、客户对封套的响应又是否满意。要是未启用OCSP Must-Staple,这其实不是个问题,但如果我们果真启用OCSP Must-Staple,然后又没有适当地或可靠地使用OCSP封套,我们的网站会开始出问题。


为了获得关于我们在OCSP封套方面怎么做的一些反馈,可以启用一项名为OCSP Expect-Staple的功能。之前这方面我写过一篇文章,可以在博客OCSP Expect-Staple(https:///ocsp-expect-staple/)中了解所有细节,不过这里将给出简短版本。你可以请求添加HSTS preload列表:如果对OCSP封套不满意,让浏览器向你发送报告。可以自行收集报告,或使用我的服务替你收集。如果你启用了OCSP Must-Staple,就能了解遇到问题的频次到底如何。


由于添加HSTS preload列表不如我希望的那么简单,我还写了一个规范,定义一个新的名为“Expect-Staple”的安全报头,以提供同样的功能,但减少了工作量。现在你可以在启用Must-Staple之前,设置该报头,并启用报告机制、以获得我们迫切需要的反馈。启用报头很简单,就像启用其他所有安全报头那样:

1 Expect-Staple: max-age=31536000; report-uri='https://scotthelme./r/d/staple'; includeSubDomains; preload


未授权证书


我们在探讨吊销话题时要考虑的另一个方面是未授权证书(rogue certificate)。要是有人设法危及CA或以其他方式获得不该拥有的证书,我们该如何知道这个情况?


如果我现在攻入了CA,获得了你网站的证书,又没有告诉你,除非此事被广泛报道,否则你蒙在鼓里。你可能甚至面临内部威胁,贵企业中某个人可能不用走适当的内部渠道就能获得证书,可以随意处理证书。我们需要有办法确保透明度达到100%,我们很快会如愿以偿,这归功于名为Certificate Transparency的开放框架。


Certificate Transparency


Certificate Transparency是一个新的要求,明年初起将是强制性要求,将要求所有证书都记录在公共日志中,如果浏览器要信任它们的话。你可以阅读该文,了解Certificate Transparency的更多详细信息,但通常发生的情况是,CA会将它颁发的所有证书记录在Certificate Transparency日志中。


Certificate Transparency日志


这种日志是完全公开的,任何人都能搜索它们,所以其想法是,如果证书是颁发给你网站的,你会了解相关情况。比如在这里(https:///?q=),你可以看到为我域颁发的所有证书,您还可以搜索自己的证书。还可以使用SSLMate的CertSpotter来搜索证书。此外,我使用Facebook Certificate Transparency Monitoring工具,每当为你域分发了新的证书,该工具会发电子邮件通知你。


Certificate Transparency是个很棒的想法,我迫不及待地希望它成为强制性要求,但它只是第一步。了解这些证书虽好,但吊销证书方面仍存在所有上述问题。话虽如此,我们每次只能解决一个问题;如果我们不知道需要吊销的证书,世界上再好的吊销机制也无济于事。Certificate Transparency至少在这方面给了我们许多。


Certificate Authority Authorization


阻止证书颁发比试图吊销证书要容易得多,这正是Certificate Authority Authorization(证书管理机构授权)让我们开始做的事情。简单来说,我们现在可以授权只有特定的CA为我们颁发证书,而不像现在我们根本无法表明任何偏好。就像创建DNS记录一样简单:

1 . IN CAA 0 issue 'letsencrypt.org'


虽然CAA不是一种特别强大的机制,它在误颁发的情况下无助于事,但是在一些情况下它能帮助我们,我们可以通过创建CAA记录来表明我们的偏好。


结束语


目前有个真正的问题:如果有人获得了我们的私钥,我们无法吊销证书。想象一下,要是下一个Heartbleed出现,那会是怎样的场面?为了限制破坏所造成的影响,你能做的事情之一是,缩短你获得的证书的有效期。改用一年或更短,而不是三年。Let's Encrypt只颁发有效期只有短短90天的证书!如果证书的生命周期缩短,即使你中了招,问题也不大,因为攻击者在证书过期之前滥用证书的时间较短。除此之外,我们几乎无计可施。


为了表明这个问题及其严重性,可以访问我在本人网站上创建的新子域:revoked.。你可能猜到了,这个子域名使用已吊销的证书,它很可能会顺利加载。要是没有,你又确实收到了关于证书已过期的警告,那么你的浏览器仍在执行OCSP检查,你只要告诉CA要访问我的网站。


为了证明这种软失效检查毫无意义,你可以为ocsp.int-x3.letsencrypt.org添加一个hosts条目,以便解析至127.0.0.1,或者通过其他方法来阻止它,然后再试一下。这回,页面会顺利加载,因为吊销检查将失效,浏览器会继续加载页面。


最后我想要说的是这个问题:我们应该修复吊销机制吗?改天再聊这个话题!


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多