SSL Pinning 和证书过期

SSL Pinning and certificate expiry

此问题涉及在客户端应用程序中针对 Web api 和证书使用 SSL Pinning 到期。

场景:

我拥有 example.com 并且有一个子域,其中托管了 api,因此:api.example.com

我希望在 SSL 上使用 api,因此为子域创建了一个 SSL 证书。

获得证书后,我有:

据我所知,我在我的网络服务器上安装了这些证书。

然后我希望我的客户端应用程序连接到 api。减轻中间人风格 攻击,我希望使用 SSL Pinning,这样客户端只会与我的 api 通信,而不是 有人在欺骗它。

为了固定在客户端应用程序中,我有两个选择,要么固定在 public 上,要么固定在中间 证书.

假设我实现了这个。

api.example.com 上的证书到期后会发生什么?

据我所知,客户端应用程序将不再工作。

我需要重新生成一整套 public/intermediate/private 项吗?接着 在应用程序中放置新的 public 或中间证书?

问题:

在 api.example.com 上的证书更新之前,我仍然希望客户端应用程序能够正常工作。 当然也可以在client app里面放一个新的证书,但是roll-out之类的东西需要时间。

我该如何处理?

我读到 Google 每个月都会更新他们的证书,但不知何故设法使 public 密钥保持不变:How to pin the Public key of a certificate on iOS

如果可能的话,解决方案是简单地从服务器中提取 public 密钥并根据本地存储的 public 密钥对其进行检查...但是 Google做吗?

谢谢

克里斯

注意:我更熟悉浏览器到服务器固定(HTTP Public Key Pinning - HPKP)而不是应用程序到服务器固定,但我认为原理是相同的。在 HPKP 中,固定策略由服务器作为 HTTP header 提供,但请理解这通常内置于应用程序中,而不是从 HTTP 响应中读取。因此,请记住以下所有内容,然后阅读以下答案:

固定通常是针对密钥而不是证书,并且可以是多个级别。所以你有几个选择:

  1. 重复使用相同的 key/crt 生成新证书。有些人(在我看来是正确的!)建议在每次更新证书时生成一个新密钥,但是当您使用固定时这很复杂。那么固定是否会助长不良的安全习惯,例如密钥重用?

  2. 在您的固定策略中有几个备份密钥,并在证书续订时轮换它们,丢弃最旧的并添加一个有足够时间和更新的新密钥,永远不会短缺。就我个人而言,我更喜欢在证书更新时生成密钥,而不是有一些可能或可能已经被破坏的备份,所以我也不是特别喜欢这个。你应该有多少备份?例如。如果您因为续订方面的妥协而需要重新颁发证书并且还搞砸了?那么2? 3? 100?

  3. 再往上钉。说第一个中间或根 CA 证书。因此,任何新颁发的证书仍然是可信的(前提是它是由相同的证书路径颁发的)这样做的缺点有四:i)你仍然对 miss-issued 由该固定证书颁发的证书开放(恕我直言,这不是什么大不了的事)因为您仍然大大减少了攻击面,但仍然引起某些人的关注),ii)您不能保证客户端会使用该中间证书,因为有时会有多个有效路径。这第二个是一个更大的交易。您可能认为提供中间证书可以保证使用它,但事实并非如此(有很多 sha-1 示例)。 iii) 不能保证新证书将由相同的中间体或根颁发(尤其是当技术发生变化时,如引入 sha2),所以对我来说,这整个选项是 non-starter iv)它使您只能使用相同的证书提供者(也许没什么大不了的,但我喜欢移动的自由)。不确定应用程序本身是否支持此功能,但浏览器肯定支持。

  4. 提前更新,在策略缓存过期之前不要使用新密钥。例如,如果您有一年的证书和 30 天的固定政策,那么您可以在 11 个月后续订,将新密钥添加到政策中,然后等待 30 天,这样您就可以确定每个人都会接受新政策或至少旧政策将过期,然后切换密钥和证书。取决于短期政策,但可能会浪费其中的一部分(在此示例中至少 30 天),除非证书提供商在旧政策到期后的第二天开始提前提供证书。对于应用程序,如果固定策略被硬编码到其中,那么这可能涉及推送更新所需的时间长度。

最后,因为证书确实需要更新,所以我不太喜欢固定。我不认为 定期更新的东西,semi-permanent 是正确的答案。甚至有人谈论 pre-loading 浏览器中的固定策略,这让我不寒而栗。

固定可以确保流氓 CA 不会为您的域颁发证书,但与固定的麻烦相比,这真的有多大可能?诸如证书透明度之类的东西 - 甚至仅报告固定可能是该问题的更好答案,即使它们实际上并没有阻止该攻击。

最终在本地安装了根目录(例如用于防病毒扫描程序或公司代理),绕过固定检查(至少在浏览器上),这再次降低了它在我眼中的有效性。

所以在使用固定之前请仔细考虑并确保您了解所有后果。

mozilla developer site 建议固定签署服务器证书的中间 CA 的证书。

"it is recommended to place the pin on the intermediate certificate of the CA that issued the server certificate, to ease certificates renewals and rotations."

有关实施和测试 public 键固定的更多信息,您可以参考 Implementing and Testing HTTP Public Key Pinning (HPKP)

您的应用程序可以在其 pin 列表中存储多个证书。更改证书的过程将是:

  • 在证书过期前的某个时间,在 pin 列表中使用替换证书以及原始证书发布应用程序的新版本
  • 当旧证书过期时,在服务器上替换它 - 应用程序应该仍然可以工作,因为新证书已经在 pin 列表中
  • 证书过期一段时间后,发布应用的新版本,删除旧证书

请记住,您的用户必须在旧证书过期之前更新应用程序