SSL 固定和证书验证之间的区别

Difference between SSL pinning and certificate validating

有人可以解释验证证书与此处描述的自签名证书之间的区别吗:

https://jetforme.org/2013/05/validating-a-self-signed-ssl-certificate-in-ios-and-os-x-against-a-changing-host-name/

和此处所述的 SSL 固定:

https://infinum.co/the-capsized-eight/how-to-make-your-ios-apps-more-secure-with-ssl-pinning

谢谢

首先让我们澄清一下Cocoa世界中的术语:

  • A SecPolicyRef 是一种策略,它定义了验证证书链时的规则:链中证书中要检查的内容(签名、到期日期等),它确定证书是否chain 是 valid/trusted 还是不是。
  • 一个SecTrustRef对象是一个证书链(基本上是一个SecCertificateRef的数组)和一个SecPolicyRef的组合。此对象表示验证证书链所需的所有内容(证书 + 策略)。

验证服务器的证书链包括两个步骤:

  1. 需要验证证书路径(签名、到期日期等)以确保服务器证书是由受信任的 CA 颁发的。
  2. 为其颁发服务器证书的名称(通用名称或主题备用名称)需要与应用程序尝试连接的服务器名称相匹配。

这些步骤用SecPolicyRef表示:

  • SecPolicyCreateBasicX509() returns 一项包含所有需要检查的内容的政策 1;这是出于历史原因,但绝不能使用。
  • SecPolicyCreateSSL() returns 具有 1 和 2 的所有规则的策略;这是你必须使用的。

然后您使用 SecTrustEvaluate() 来验证服务器的 SecTrustRef。结果将根据传递的 SecPolicyRef 告诉您服务器的证书链是否可信。

最后,SSL 固定意味着在整个过程中添加第三步:

  1. 证书链必须包含特定的密钥或证书。这确保应用程序只会接受您知道自己部署在服务器上的证书,而不是任何 CA 为您的域颁发的任何证书。

我建议不要编写您自己的 SSL 验证实现(有或没有固定),因为您可以看出,API 非常复杂,并且很可能出现巨大的错误,这会使您的应用程序极度不安全。

我开发了一个库来简化 SSL 固定;它在 https://github.com/datatheorem/TrustKit 可用,并负责所有繁重的工作。