【发布时间】:2021-10-18 13:39:34
【问题描述】:
我想使用 SSL Pinning 保护我的应用免受中间人 (mitm) 攻击。
默认情况下,可以使用 Charles 或 mitmproxy 等代理来拦截流量,并使用自签名证书对其进行解密。
经过大量研究,我找到了几个选择:
-
将
NSPinnedDomains > MY_DOMAIN > NSPinnedLeafIdentities添加到Info.plist
苹果文档:Identity Pinning
卫士广场:Leveraging Info.plist Based Certificate Pinning
优点:简单
缺点:一旦更新证书/私钥(通常在几个月后),应用程序将无法使用 -
将
NSPinnedDomains > MY_DOMAIN > NSPinnedCAIdentities添加到Info.plist
苹果文档:same as above
优点:简单。叶证书续订没有失败,因为根 CA 被固定(过期日期为几十年)
缺点:似乎是多余的,因为大多数根 CA 都是 already included in the OS -
检查代码
URLSessionDelegate>SecTrustEvaluateWithError(或 Alamofire 包装器)中的证书
雷·温德利希:Preventing Man-in-the-Middle Attacks in iOS with SSL Pinning
苹果文档:Handling an Authentication Challenge
中篇:Everything you need to know about SSL Pinning
中篇:Securing iOS Applications with SSL Pinning
优点:更灵活。可能更安全。 Apple 推荐(请参阅上面的 Apple 链接)。
缺点:(1)或(2)的一个更费力的版本。关于叶子到期/根 CA 冗余的缺点与 (1) 和 (2) 相同。更复杂。 -
将 NSExceptionDomains > MY_DOMAIN > NSRequiresCertificateTransparency 添加到 Info.plist
苹果文档:Section Info.plist keys 'Certificate Transparency'
优点:非常简单。没有多余的 CA 集成。
缺点:文档不清楚这是否应该用于 ssl pinning
经过评估,我得出以下结论:
- 由于证书过期,不适合生产应用
- 可能是简单性、安全性和可持续性之间的最佳平衡 - 但我不喜欢重复添加系统已经知道的根 CA
- 太复杂,太冒险,任何实现错误都可能锁死应用
- 我的首选方式。简单的。在我的测试中有效,但文档不明确。
我很想使用选项 (4),但我不确定这是否真的适用于 ssl pinning。
在文档中它说:
证书透明度 (CT) 是 ATS 可用于识别错误或恶意颁发的 X.509 证书的协议。将 NSRequiresCertificateTransparency 键的值设置为 YES 以要求对于给定域,服务器证书由来自 Apple 信任的至少两个 CT 日志的有效签名 CT 时间戳支持。有关证书透明度的更多信息,请参阅 RFC6962。
在链接的 RFC6962 中:
本文档描述了一个实验性协议,用于公开记录传输层安全 (TLS) 证书的存在 [...]
“实验性协议”和“公开记录”这两个术语对我来说很重要,尽管在 Info.plist 中启用该功能似乎可以解决 SSL 固定问题,但我不确定是否应该使用它。
我绝不是安全专家,我需要一个非常简单的解决方案,它可以为我提供体面的保护,同时防止我自己的应用程序因可能过期/更改的证书而窒息。
我的问题:
我应该使用NSRequiresCertificateTransparency 来固定我的应用程序并防止中间人攻击吗?
如果不是:
我应该改用什么?
PS:
这个帖子基本上已经问过同样的问题:
https://developer.apple.com/forums/thread/675791
但是关于NSRequiresCertificateTransparency(4. 在我上面的列表中)的答案很模糊:
没错,Certificate Transparency 是一个很好的工具,可以通过 TLS 扩展(可以在 Packet Trace 中看到)验证提供的叶子是否包含一组嵌入在证书 (RFC 6962) 中的 SCT(签名证书时间戳) ),或通过检查证书的 OCSP 日志。当您在应用中做出信任决定时,我建议您通过 SecPolicyRef 对象查看 is 属性。
补充说明:
我对 Apple 作为一家具有安全意识的公司的期望是,默认情况下会启用固定到根 CA,并且我必须手动添加例外,例如允许在调试版本中使用 Charles 代理。 我听说 Android 就是这样做的。
【问题讨论】:
标签: ios swift certificate-pinning public-key-pinning sslpinning