在一个子域名上,NSURLSession/NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802)?

3

我们的应用程序在生产和开发环境中都能正常工作,但在我们的演示环境中,我们遇到了常见的错误:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

据我了解,当您尝试连接到非 https URL 时,会出现此错误。

  • 我们在本地隧道中使用 ngrok,它具有 https URL 并且可以正常工作。
  • 对于生产环境,我们也使用 https://ourdomain.com,并且它可以正常工作。
  • 对于测试环境,我们使用 https://staging.ourdomain.com,但是会出现这个错误。

我看到很多解决方案都建议执行以下操作:

<key>NSAppTransportSecurity</key>
 <dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

但是我的雇主反对禁用ATS来使暂存工作,他也反对为我们的 staging URL 添加异常。

有什么想法,为什么我们的暂存URL会导致这个错误抛出或如何修复它吗?

ATS诊断输出:

Starting ATS Diagnostics

Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://staging.domain.co.
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
================================================================================

Default ATS Secure Connection
---
ATS Default Connection
ATS Dictionary:
{
}
Result : PASS
---

================================================================================

Allowing Arbitrary Loads

---
Allow All Loads
ATS Dictionary:
{
    NSAllowsArbitraryLoads = true;
}
Result : PASS
---

================================================================================

Configuring TLS exceptions for staging.domain.co

---
TLSv1.2
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.2";
        };
    };
}
Result : PASS
---

---
TLSv1.1
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.1";
        };
    };
}
Result : PASS
---

---
TLSv1.0
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.0";
        };
    };
}
Result : PASS
---

================================================================================

Configuring PFS exceptions for staging.domain.co

---
Disabling Perfect Forward Secrecy
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring PFS exceptions and allowing insecure HTTP for staging.domain.co

---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled for staging.domain.co

---
TLSv1.2 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.2";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.1 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.1";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.0 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.0";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for staging.domain.co

---
TLSv1.2 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.2";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.1 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.1";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.0 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.0";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

你找到解决方案了吗?我也运行了 nscurl,所有的测试都通过了。 - ricardopereira
1个回答

9

App Transport Security不仅涉及HTTP与HTTPS。为了避免ATS问题,您需要使用配置正确的服务器和证书。根据苹果文档[1]:

服务器必须支持至少传输层安全性(TLS)协议版本1.2。连接密码限于提供前向保密的密码。证书必须使用SHA256或更高签名哈希算法进行签名,并使用2048位或更高RSA密钥或256位或更高的椭圆曲线(ECC)密钥。无效的证书会导致硬性失败和无法连接。

如果您使用OS X 10.11(或更高版本),可以使用nscurl进行故障排除。打开终端并运行以下内容:

/usr/bin/nscurl --ats-diagnostics https://staging.ourdomain.com

[1] https://developer.apple.com/library/ios/technotes/App-Transport-Security-Technote/index.html

这是一篇关于iOS应用程序传输安全的技术笔记。它讨论了如何在应用程序中实现传输安全,以保护用户数据和隐私。如果您是iOS开发人员或对移动应用程序安全感兴趣,这篇文章将对您有所帮助。请点击上面的链接查看完整内容。

你能贴上nscurl的输出吗,这样我们就可以看一下了吗?你可能还想在执行时加上"--verbose"开关。 - Ryan LaNeve
嗯...第一个测试通过了 - “默认ATS安全连接” - 应该表明您的服务器已正确配置,您不应该遇到ATS问题。话虽如此,我想如果nscurl不是一个足够的测试,那么也是可能的。但如果它不是,我会感到惊讶,但这是有可能的。您能否尝试使用SSL Labs网站来检查您的暂存服务器呢?其输出将更全面地描述您的服务器配置情况。 https://www.ssllabs.com/ssltest/index.html此外,您已经尝试了NSAllowArbitraryLoads密钥吗?它是否解决了问题? - Ryan LaNeve
我还没有尝试过任意负载。我已经向我的经理提出了这个解决方案,但他不喜欢绕过问题的想法,即使它在暂存中。 - Deekor
我同意你的经理。然而,为了解决这个问题,我建议你进行更改以打开NSAllowArbitraryLoads,只是为了看看它是否有效。你可以立即恢复更改。如果有效,那么你就有一个ATS问题。如果不起作用,那么你就没有ATS问题。你从nscurl得到的结果表明你没有ATS问题。 - Ryan LaNeve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接