了解证书固定

2020-06-16 00:03:54

证书钉住(简称“证书钉住”)是一种用于移动应用程序的技术,用于添加额外的保护层来保护通信安全。一些人还使用该技术通过拦截代理来防止人们对API进行反向工程,然而,后一个目标很难在有决心的黑客面前实现。

证书固定提供了非常高的安全性,但也有一些需要企业考虑的缺点。本博客解释了证书固定的安全和业务注意事项,并显示了根据实施它的组织的需要可以进行的权衡。

证书固定通常是以强制移动应用程序升级为代价的,对于短期证书(如We‘s Encrypt提供的证书)而言,这可能是一种特别痛苦的用户体验。

受证书固定的应用程序需要与轮换证书的运营团队协作推出新版本,因为升级应用程序需要时间(包括AppStore审核)-否则将出现停机。

证书颁发机构固定的选项不如完全证书固定严格。它需要的维护较少,同时提供的安全性略低,但仍具有很强的安全性。

要了解证书锁定,必须了解PKI。这方面有一个很棒的博客是由技术爱好者提供的:适用于哑巴的SSL/TLS,第3部分-了解证书颁发机构-令人尴尬的是,他们的证书在撰写本文时已经过期,所以只需阅读下面的内容即可。

简单地说,互联网上的安全通信是通过TLS完成的(人们经常错误地说成“SSL”,它是TLS的前身,由于安全漏洞而被弃用)。TLS的安全依赖于一小部分称为证书颁发机构(CA)的组织,它们的角色是验证身份,然后向网站颁发证书,从而允许它们使用TLS安全。要使这一切正常工作,操作系统和可能的其他软件提供商需要从证书颁发机构获得一小部分证书-这些证书是TLS中其他一切都依赖的“根级”证书。当您通过TLS访问网站时,该网站提供的证书需要根据其中一个根级CA检查其签名以验证其有效性-这会断言您正在访问您认为正在访问的网站,并且假定CA未被攻破、操作系统/软件供应商未被攻破、您没有安装假CA并且您正在访问的网站已充分保护其私钥,则该网站的通信是安全的。如果这些假设中有任何一个是错误的,那么所有的赌注都将落空。

如前所述,TLS可以通过多种方式破坏,但最严重的是证书颁发机构被破坏,因为它影响到每个人。这样的安全事件已经发生过,最突出的例子是DigiNotar,除了CA被攻破之外,还有其他一些PKI安全缺陷影响了大量人的例子,比如联想SuPerfish事件。

必须强调的是,如果任何一个CA被攻破,那么所有的TLS都会被破坏。你为你的网站使用了什么CA并不重要,重要的是你的攻击者使用了什么CA。我见过一些被认为是精通安全的大组织,他们的政策是只从他们最信任的CA子集获得证书-他们完全忽略了一点,即他们信任的CA并不重要:PKI的设计意味着我们都依赖于每个CA都不会被攻破。在本博客的最后,我们将展示这样的政策有意义的一个场景:然而,我还没有看到它在实践中得到实施。(注:公钥基础设施的设计意味着我们都依赖于它们中的每一个都不会被攻破。)在本博客的最后,我们将展示这样的政策有意义的一个场景:然而,我还没有看到它在实践中得到实施。

每个CA都需要完全安全才能使PKI工作,这是一些人不信任PKI的原因之一。然而,这就是证书钉住移动应用程序的地方:使用它的主要原因是为了弥补PKI的缺点。证书固定的概念是使移动应用程序只信任与其通信的网站上使用的确切证书,从而不再依赖CA的安全性。实现这一点的一种方法(稍后将提到其他更实用的方法)是在开发期间在移动应用程序源文件中提供确切的证书(或其加密散列),并编写代码来验证此证书与网站在TLS通信的初始阶段发送的内容是否匹配。如果不存在完全匹配,则拒绝通信并不继续。这提供了非常强大的安全性,但它确实伴随着一些潜在的陷阱,我们稍后将对此进行解释。

有些人使用证书钉住还有第二个原因,那就是防止人们通过拦截代理对你的移动应用进行反向工程。没有证书固定,任何人都可以使用众所周知的技术查看他们的移动应用程序和服务器之间的通信(参见此处和此处)。这并不是破坏TLS-其他人无法检查您的通信,只有您可以通过在您的移动设备上安装拦截代理证书来检查您自己的通信。通过添加操作系统信任且您知道私钥而其他人都不知道的新证书,您就可以窥探TLS通信,但其他人都不能。如果由于应用程序停止拦截而固定了证书,则这不会直接起作用-它不信任新安装的证书,而是只信任固定的确切证书。

然而,这种防御的效果有限,因为可以使用众所周知的技术绕过证书固定(请参见此处和此处),而且理解API工作原理的另一种方法是老式的二进制逆向工程。因此,为了防止攻击者理解您的API,您还需要混淆和越狱/根检测。这样的防御可以阻止许多黑客,但一个技术娴熟、意志坚定、拥有大量空闲时间的黑客最终可以成功。

总而言之,进行证书固定以防止潜在的PKI不安全是有意义的,但是证书固定并不能阻止人们理解您的API-它只会减慢优秀的黑客的速度。在本博客的其余部分,我们主要关注使用证书锁定来处理潜在的PKI问题。降低反向工程速度的证书锁定不在本博客的讨论范围内。

操作系统供应商/移动设备制造商对确保安全有着浓厚的兴趣:人们信任他们的产品对他们的业务成功非常重要。因此,当CA不再受信任时,他们通常会向客户推送安全更新。例如,当DigiNotar受到攻击时,苹果发布了更新。浏览器制造商也进行了类似的更新,正如这里所描述的那样。

因此,这给了我们一些保证,即使没有证书固定,我们仍然可以拥有良好的安全性。然而,有一些陷阱:

用户并不总是及时安装他们的安全更新,因此在可能利用漏洞时存在差距。

这只适用于已知的危害,而证书锁定将防止未知的危害。

Android的情况就不那么令人放心了,因为安全更新是由谷歌通过移动设备供应商提供的,而供应商在向用户推送安全更新时并不总是那么迅速。

与(3)相关的是,谷歌确实为应用开发者提供了一个解决方案,通过使用API installIfNeededAsync()或installIfNeededAsync()来保护客户端免受发现的TLS漏洞的攻击,而无需依赖供应商的安全更新。*从文档中我不清楚这是只修复了TLS实现错误,还是还更新了设备上的根证书。

因此,虽然存在一些后备问题,但使用证书固定等技术绝对有提高安全性的空间。然而,需要注意的是,证书固定有一个实际的缺点-当证书更改时,应用程序会中断。我们稍后会更多地讨论这个问题。

有趣的是,我们对移动安全的要求如此之高,但相应的Web浏览器安全又如何呢?我们拥有类似控件的能力受到一定程度的限制,所以人们可能会觉得我们对待移动应用程序比对待浏览器更神圣。

2015年,安全界试图通过向网络浏览器引入类似的概念来弥补移动安全指导和网络浏览器安全能力之间的差异。添加了新的HTTP报头,该报头允许网站指示浏览器固定其证书,因此浏览器将不接受来自该特定网站的任何其他证书(在报头中指定的有效期内)。这称为HTTP公钥锁定(HPKP)。

没过多久,安全界就发现了这项提议的问题。在两年内,HPKP的一位作者宣布由于一些以前没有预料到的问题而打算弃用它。弃用的原因包括难以选择一套保证有效的密码、如果密码错误会把用户锁在门外的风险,以及攻击者若能取得错误的证书便会滥用HKPK的风险。这里有一个锁定用户的真实示例。使用弃用时,建议替换为:Expect-CT标头。Expect-CT标题在此正式记录。

Expect-CT不如证书钉住强大,但使用起来更安全(尽管如此,作者建议谨慎使用)。简而言之,它是用来指示浏览器网站必须拥有已发布的证书,以符合谷歌的证书透明度努力。通过某些配置,可以指示浏览器在站点不符合要求的情况下阻止连接。因此,如果恶意行为者秘密获得了一个网站的未发布的、未被起诉的证书,他将不能在该网站上滥用该证书。换句话说,恶意行为者滥用失败的证书,它需要是一个已发布的证书!但希望这些滥用可以通过证书吊销来捕获(也可能不会)。

在撰写本博客时,许多浏览器(包括Firefox)都不支持Expect-CT。这是朝着修复PKI缺点迈出的一大步,但略落后于移动证书绑定所获得的安全性。

Infinium公司已经为开发人员编写了关于如何实现证书固定的优秀博客。这些指南可在以下位置找到:

需要强调的证书固定的一个关键缺点是,更改证书意味着您需要发布新版本的应用程序(下面将讨论一个例外),并强制将用户升级到最新版本。这是因为应用程序只使用固定的确切证书-如果使用任何其他证书,通信中断。如果您使用的是短期证书,比如“让我们加密”中的证书,那么这需要频繁的维护,并且不会给您带来令人愉快的用户体验。

另一点是,证书的轮换将需要与更新后的APP的发布进行协调,以避免停机。这意味着开发团队需要足够的提前通知,才能用新证书更新APP,对其进行测试和审核,并让其通过App Store审核,否则用户可能会被锁定一段时间。这是一个非常令人担忧的问题:我亲眼目睹了这种情况的发生,而企业并不高兴。

上面提到的例外是,如果只固定了公钥(与完整证书相反),那么只要在新证书中使用相同的公钥,就可以在不发布新应用程序的情况下轮换证书。也就是说,您在证书过期时更改证书,但使用与以前相同的加密密钥。这会带来更友好的用户体验,但它要求管理证书的人员(通常是操作团队)遵循开发团队的要求。当然,如果有任何关键的变化,需要发布新的应用程序,并且需要进行强制升级。

还有另一个选项提供的安全性略低于完整证书固定,但更有可能避免需要发布新应用程序并强制升级用户…的问题。

为了消除在发布新证书时升级应用程序的需要,但仍然希望获得比TLS更好的安全性,开发人员只能固定证书颁发机构的公钥。换句话说,除了安全所需的所有常规证书检查之外,应用程序现在将只接受由您允许的特定CA(或多个CA)签名的证书,而不接受其他CA签名的证书。

回想一下我们上面关于PKI问题的讨论:如果任何CA被攻破,那么每个人都会变得易受攻击。但是,通过固定我们信任的一个或多个CA的证书,我们就不再有这种风险。取而代之的是,我们信任的确切CA需要受到损害,才能使我们变得脆弱。

这不像完全证书锁定那样强大,因为如果信任链中的中间密钥受损,那么您仍然容易受到攻击。但是,它比仅使用TLS要好,因为现在您不依赖于所有CA都是安全的:相反,您只依赖您正在使用的一个或多个CA是安全的。

使用此方法时,仅当您更改CA或CA更改其公钥时,才需要更新应用程序。如果您的公司有限制CA的策略,那么您可以锁定这些CA的公钥,并且很可能在很长很长一段时间内都不需要担心更新应用程序或强制升级。这对那些使用短期证书的人特别有吸引力。