【问题标题】:System.AggregateException thrown when trying to access server on Xamarin.Forms Android尝试访问 Xamarin.Forms Android 上的服务器时引发 System.AggregateException
【发布时间】:2022-01-24 12:18:43
【问题描述】:

我使用HttpClient 与我的服务器通信,如下所示:

private static readonly HttpClientHandler Handler = new HttpClientHandler
                                                                 {
                                                                     AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
                                                                     AllowAutoRedirect      = true,
                                                                 };
    
private static readonly HttpClient Client = new HttpClient(Handler, false);

问题是我在 Android 上遇到了 System.AggregateException 异常。可以在下面的屏幕截图中看到异常详细信息:

应用在 iOS 上运行良好。

服务器正在使用Let's Encrypt 证书,并且从一周前更新证书后问题才浮出水面。

我已经检查了有关证书有效性的任何内容(过期、DNS 名称等),一切似乎都正常。

【问题讨论】:

  • 重要的一点在Message 属性中,就在突出显示的InnerException 下方:开始“Ssl 错误:1000007d”的那个。你能把所有的都贴出来吗?
  • 通过应用您的回复中的洞察力来纠正整个情况。我最终在服务器上编辑了fullchain.pem,但我想你的建议 1 是最优雅的。我会尝试并更新。

标签: c# android xamarin xamarin.forms lets-encrypt


【解决方案1】:

这是 Xamarin.Android 中的一个长期存在的问题 #6351,由 LetsEncrypt 的根过期并且它们移动到新根引起。

下面是my post in that issue 的副本,解释了这种情况和解决方法。有关解决方法的详细信息,请参阅该主题中的其他帖子。


Scott Helme 对这种情况进行了精彩的描述。先去阅读,然后我将描述(我认为)这如何适用于 xamarin-android。

我将复制那篇文章中的关键图 (source):

红色链是过去发生的情况:IdenTrust DST Root CA X3 是一个旧的根证书,几乎在任何地方都受信任,包括从 2.3.6 开始的 Android 设备。这就是 LetsEncrypt 过去使用的根,这意味着每个人都信任他们。但是,这个 IdenTrust DST Root CA X3 最近过期了,这意味着一堆设备不会信任任何由它签名的东西。 LetsEncrypt 需要移动到他们自己的根证书。

蓝色链是理想的新链——ISRG Root X1 是 LetsEncrypt 自己的根证书,包含在 Android 7.1.1+ 中。 Android 设备 >= 7.1.1 将信任已由此 ISRG Root X1 签名的证书。

但是,问题在于旧的 7.1.1 之前的 Android 设备不知道 ISRG Root X1,也不信任它。

LetsEncrypt 使用的解决方法是旧的 Android 设备不检查根证书是否已过期。因此,它们默认提供一个链,其中包括 LetsEncrypt 的根 ISRG Root X1 证书(最新设备信任),但还包括来自该现已过期的 IdenTrust DST Root CA X3 的签名。这意味着旧的 Android 设备信任该链(因为它们信任 IdenTrust DST Root CA X3,并且不检查它是否已过期),而较新的设备也信任该链(因为即使链的根已经过期,他们仍然相信中间的 ISRG Root X1 证书本身就是一个有效的根,因此信任它)。

这是绿色路径,LetsEncrypt 当前默认提供的路径。

但是,xamarin-android 使用的 BoringSSL 库不是 Android 的 SSL 库。它 1) 不信任 IdenTrust DST Root CA X3,因为它已过期,并且 2) 不够聪明,无法确定它确实信任也在链中的 ISRG Root X1。因此,如果您为上图中的绿色链提供服务,它就不信任它。盖克。

因此选项是:

  1. 不要使用 BoringSSL,而是使用 Android 的 SSL 库。这意味着 xamarin-android 的行为与其他 Android 应用程序相同,并且信任过期的根。如前所述,这是通过使用AndroidClientHandler 完成的。这应该可以修复 Android >= 2.3.6。
  2. 请使用 BoringSSL,但从 Android 的信任库中删除过期的 IdenTrust DST Root CA X3(设置中的“Digital Signature Trust Co. - DST Root CA X3”)。这会欺骗 BoringSSL 在它信任的 ISRG Root X1 处停止其链(在 Android 7.1.1+ 上)。但是,这仅适用于信任 ISRG Root X1(7.1.1+)的 Android 设备。
  3. 请使用 BoringSSL,并使用--preferred-chain "ISRG Root X1" 更改您的服务器以提供以 ISRG 根 X1 为根的链,而不是过期的 IdenTrust DST 根 CA X3(上图中的蓝色链)。这意味着 BoringSSL 完全忽略了 IdenTrust DST Root CA X3,并植根于 ISRG Root X1。这再次仅适用于信任 ISRG Root X1 的 Android 设备,即 7.1.1+。
  4. 执行与 3 相同的操作,但通过手动编辑 fullchain.pem。
  5. 使用另一个 CA,例如 ZeroSSL,它使用的根目录受 Android 2.2 的信任,并且在 2038 年之前不会过期。

【讨论】:

  • 很好,很彻底!谢谢你。不过,还有一件模糊的事情留给我。 - 如果我没记错的话,根 CA 在 9 月左右的某个时间过期。在那之后我已经更新了我的证书一次,并且直到几天前它都可以正常工作。这里缺少一些东西,不是吗?另外,关于您的第一个建议,人们可以查看this GitHub gist
  • 有趣。我不知道如何解释——也许 BoringSSL 实际上是因为根在订阅者证书上的“Not Before”日期之前过期的事实而窒息?这符合数据,但这是一个有点奇怪的检查。
  • 实际上考虑一下,在订阅者证书有效时检查根是否有效是一个明智的检查,并且符合数据,所以这可能就是正在发生的事情。您的旧订户证书是有效的,因为根 在其签署时是有效的
猜你喜欢
  • 1970-01-01
  • 2023-02-08
  • 1970-01-01
  • 2014-08-26
  • 1970-01-01
  • 2014-02-19
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多