使用 Info.plist 中的 NSRequiresCertificateTransparency 键进行 iOS TLS/SSL 固定

de.*_*de. 5 ios swift certificate-pinning public-key-pinning sslpinning

我想使用 SSL Pinning 来保护我的应用程序免受中间人 (mitm) 攻击。
\n默认情况下,可以使用 Charles 或 mitmproxy 等代理来拦截流量,并使用自签名证书对其进行解密。

\n

经过广泛的研究,我发现了几种选择:

\n
    \n
  1. 添加NSPinnedDomains > MY_DOMAIN > NSPinnedLeafIdentitiesInfo.plist
    \nApple 文档:身份锁定
    \nGuardsquare:利用基于 Info.plist 的证书锁定
    \n优点:简单
    \n缺点:一旦更新证书/私钥(通常在几个月后),应用程序将变得无法使用

    \n
  2. \n
  3. 添加NSPinnedDomains > MY_DOMAIN > NSPinnedCAIdentitiesInfo.plist
    \nApple 文档:与上面相同
    \n优点:简单。叶证书续订不会失败,因为根 CA 已被固定(过期日期几十年后)
    \n缺点:似乎多余,因为大多数根 CA 已包含在操作系统中

    \n
  4. \n
  5. 检查代码中的证书URLSessionDelegate> SecTrustEvaluateWithError(或 Alamofire 包装器)
    \nRay Wenderlich:使用 SSL Pinning 防止 iOS 中的中间人攻击\n
    \nApple 文档:处理身份验证质询
    \nMedium 文章:有关 SSL Pinning 您需要了解的所有信息
    \n中型文章:使用 SSL Pinning 保护 iOS 应用程序
    \n优点:更灵活。可能更安全。由 Apple 推荐(请参阅上面的 Apple 链接)。
    \n缺点:(1)或(2)的更费力的版本。关于叶过期/根 CA 冗余的缺点与 (1) 和 (2) 相同。更复杂。

    \n
  6. \n
  7. 将 NSExceptionDomains > MY_DOMAIN > NSRequiresCertificateTransparency 添加到 Info.plist
    \nApple 文档:Info.plist 部分键 \'证书透明度\'
    \n优点:非常简单。无冗余 CA 集成。
    \n缺点:文档不清楚这是否应该用于 ssl pinning

    \n
  8. \n
\n

经过评估,我得出以下结论:

\n
    \n
  1. 由于证书过期,不适合生产应用程序
  2. \n
  3. 可能是简单性、安全性和可持续性之间的最佳平衡 \xe2\x80\x93 但我不喜欢重复添加系统已经知道的根 CA
  4. \n
  5. 太复杂,风险太大,任何实施错误都可能锁定应用程序
  6. \n
  7. 我首选的方式。简单的。在我的测试中有效,但 \xe2\x80\x93 文档不清楚。
  8. \n
\n

我很想使用选项 (4),但我不确定这是否真的用于 ssl 固定。

\n

在文档中它说:

\n
\n

证书透明度 (CT) 是 ATS 可以用来识别错误或恶意颁发的 X.509 证书的协议。将 NSRequiresCertificateTransparency 键的值设置为 YES,以要求对于给定域,服务器证书由来自至少两个 Apple 信任的 CT 日志的有效签名 CT 时间戳支持。有关证书透明度的更多信息,请参阅 RFC6962。

\n
\n

在链接的 RFC6962 中:

\n
\n

本文档描述了一种用于公开记录传输层安全 (TLS) 证书存在性的实验协议 [...]

\n
\n

“实验协议”和“公开日志记录”这两个术语对我提出了质疑,虽然在 Info.plist 中打开该功能似乎可以解决 SSL 固定问题,但我不确定是否应该使用它。
\n我绝不是安全专家,我需要一个非常简单的解决方案,为我提供体面的保护,同时保护我免于因可能过期/更改的证书而阻塞我自己的应用程序。

\n

我的问题:

\n

我应该使用NSRequiresCertificateTransparencyssl pinning 并防止我的应用程序受到中间人攻击吗?

\n

如果不:

\n

我应该用什么来代替?

\n
\n

附:

\n

本质上已经在这个线程中提出了同样的问题:
\n https://developer.apple.com/forums/thread/675791

\n

然而,答案很模糊NSRequiresCertificateTransparency(4.在我上面的列表中):

\n
\n

是的,证书透明度是一个很好的工具,用于验证提供的叶子是否包含一组 SCT(签名证书时间戳),或者通过 TLS 扩展(可以在数据包跟踪中看到)嵌入在证书 (RFC 6962) 中,或者通过检查证书的 OCSP 日志。当您在应用程序中做出信任决定时,我建议通过 SecPolicyRef 对象查看属性。

\n
\n

附加旁注:

\n

作为一家具有安全意识的公司,我对 Apple 的期望是,默认情况下启用固定到根 CA,并且我必须手动添加例外,例如允许在调试版本上使用 Charles 进行代理。\n我听说 Android 是这样做的方式。

\n

Ruf*_*all 1

为您提供的额外资源是 OWASP。最好遵循他们对所有平台的建议。

https://owasp.org/www-community/controls/Certificate_and_Public_Key_Pinning

至于你的观点:

  1. 当证书更改时,公钥并不总是更改(叶证书通常每年轮换?)。这是固定公钥的优点之一。

  2. “缺点:似乎是多余的,因为大多数根 CA 已包含在操作系统中”正如您在此处所说,固定根证书是没有意义的,因为该证书可能已经受到操作系统的信任。

但是,从您链接到的文档中:“固定的 CA 公钥必须出现在中间证书或根证书的证书链中。固定密钥始终与域名相关联,除非满足固定要求,否则应用程序将拒绝连接到该域。

您将在此处固定中间证书。为了让您安心,您可以进行测试来打印根证书+中间证书的公钥并证明它们不匹配。

  1. “太复杂,风险太大,任何实施错误都可能锁定应用程序。” Apple 在其技术说明中提供了一个实现,您可以手动测试所有代码路径。另外,正如 owasp 所建议的,您可以查看信任套件。我似乎有一个实现,在这里您可以选择仅固定中间证书(不是根)与叶节点证书。中级证书的有效期通常为 5-10 年。

  2. 我会推迟这一点,因为我个人不确定,我认为这可能只是除了证书固定之外您可能想要使用的额外检查。owasp文档中似乎也没有提到这一点。

就我个人而言,如果我正在编写一个新应用程序,我会选择选项 1。自 android N 以来,操作系统提供了类似的方法,这意味着您也可以与 Android 对应项保持同步,并且它们也只需在您更新时更新做,反之亦然。https://developer.android.com/training/articles/security-config.html#CertificatePinning

我不是安全专家,但我根据我在大型公司工作的经验(这些公司对其应用程序进行了渗透测试)给出了我的想法。如果您确实正在开发需要高安全性的应用程序,那么您确实应该让渗透测试人员测试您的应用程序。如果您在一家大公司,您可能会有一个可以提供帮助的网络团队。