证书固定 - 仅公钥?

Posted

技术标签:

【中文标题】证书固定 - 仅公钥?【英文标题】:Certificate Pinning - Public Key only? 【发布时间】:2013-03-30 10:10:29 【问题描述】:

我想将根 CA (verisign - http://www.verisign.com/repository/roots/root-certificates/PCA-3G5.pem) 的公钥固定到我的 ios 应用程序中。 固定公钥还是subjectPublicKeyInfo更好? 谁能解释一下哪种方法更好,为什么?

【问题讨论】:

【参考方案1】:

我认为最好固定主题的公钥而不是根的 CA 公钥。 以下是我对固定 CA 的根 pkey 的不同权衡的理解:

好的 只要您保留相同的 CA,您就可以一遍又一遍地更新您的证书,并且它始终有效。

不好的 我相信你会稍微更容易受到 MITM 攻击的影响,因为 MITM 攻击会固定根 CA 的 pkey 而不是主题公钥,因为你会将该 CA 签名的任何证书视为有效,而不仅仅是那些真正匹配你的主题的证书。

那么固定主题的公钥呢? 基本上,您应该比固定 CA 的公钥更安全一些,并且您的应用程序即使在证书过期并续订之后也应该继续工作,只要您保持相同的公钥。

我刚刚发布了一个关于如何固定公钥的问题和解决方案,希望对您有所帮助: How to pin the Public key of a certificate on iOS

【讨论】:

【参考方案2】:

我想固定根 CA 的公钥...

只是自行车脱落,但固定服务器或服务的证书或公钥可能更安全,而不是根证书或中间证书。如果您使用的是 DigiCert 或 Verisign 等公共 CA(而不是私有的企业 CA),则尤其如此。

在公共 CA 的情况下,CA 可能会错误地颁发第二个证书,客户端将无法区分“真实”证书(颁发给您的证书)和“假”证书(错误颁发的证书) )。这在现实生活中已经发生过很多次了,所以你应该期待它会再次发生。

固定公钥还是subjectPublicKeyInfo更好?谁能解释一下哪种方法更好,为什么?

最好固定公钥(至少在固定服务器证书的情况下)。

某些组织(例如 Google)每 30 天左右轮换一次服务器证书。但是,他们重新认证了相同的公钥。例如,参见android 4.2 and Pinning。这意味着您将观察到“密钥连续性”,但不是“证书连续性”。

重新认证相同的公钥是 CertPatrol 在某些情况下在用户体验中失败如此糟糕的原因。在 Google 服务等情况下,我们确实需要公钥巡逻。

【讨论】:

【参考方案3】:

最好固定 SPKI(主题公钥信息),因为它包含实际的公钥和密钥的算法(RSA、ECDSA 等)。这在 Google 的 TLS 专家的这篇文章中有更详细的描述,网址为 https://www.imperialviolet.org/2011/05/04/pinning.html:

SPKI 包括公钥的类型和一些参数以及公钥本身。这很重要,因为仅对公钥进行散列处理就会容易受到误解攻击。考虑一个 Diffie-Hellman 公钥:如果只对公钥而不是完整的 SPKI 进行散列,那么攻击者可以使用相同的公钥,但让客户端在不同的组中解释它。同样,可以强制将 RSA 密钥解释为 DSA 密钥等。

将 SPKI 固定在 iOS 应用程序中的一个挑战是 iOS 上的安全框架不提供用于解析证书和提取 SPKI 位的 API (https://nabla-c0d3.github.io/blog/2015/08/11/security-framework-wish-list/)。

好消息是,有一个开源库可以做到这一点:https://github.com/datatheorem/TrustKit。

【讨论】:

以上是关于证书固定 - 仅公钥?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 上固定证书的公钥

SSL pinning - 在 AFSecurityPolicy 中设置固定公钥而不是固定证书

仅使用公钥的 CER 证书

我们应该为外部 https 服务处理证书/公钥固定吗?

AFNetworking 受信任证书的 pin 公钥

支付宝公钥证书支付示例