【问题标题】:Some HTTPS domains fail in mono一些 HTTPS 域在单声道中失败
【发布时间】:2016-02-09 21:22:21
【问题描述】:

我有一些 HTTPS 域,无论我做什么,Mono 都无法加载其内容。

我正在 OSX 10.11.X 上编译和运行以下代码

using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

class MainClass
{
    public static bool Validator (object sender, X509Certificate certificate, X509Chain chain,
                                      SslPolicyErrors sslPolicyErrors)
    {
        return true;
    }

    public static void Main (string[] args)
    {
        ServicePointManager.ServerCertificateValidationCallback = Validator;
        WebRequest wr = WebRequest.Create (args [0]);
        Stream stream = wr.GetResponse ().GetResponseStream ();
        Console.WriteLine (new StreamReader (stream).ReadToEnd ());
    }
}

使用以下命令编译代码

mcs test.cs /r:System.dll /r:Mono.Security.dll

并在此通过例如调用http s://davidwalsh.name来执行

mono tlstest.exe https://davidwalsh.name

即使我已确定我接受证书是什么,它也会失败并显示此消息

Unhandled Exception:
System.Net.WebException: Error: SendFailure (Error writing headers) ---> System.Net.WebException: Error writing headers ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
  at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (IAsyncResult asyncResult) <0x37e5fb8 + 0x000e3> in <filename unknown>:0
  at Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord (IAsyncResult ar, Boolean ignoreEmpty) <0x37e5f10 + 0x0001f> in <filename unknown>:0
  at Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (IAsyncResult result) <0x37da130 + 0x0019b> in <filename unknown>:0
  --- End of inner exception stack trace ---
  at System.Net.WebConnection.EndWrite (System.Net.HttpWebRequest request, Boolean throwOnError, IAsyncResult result) <0x37e7408 + 0x00183> in <filename unknown>:0
  at System.Net.WebConnectionStream+<SetHeadersAsync>c__AnonStorey1.<>m__0 (IAsyncResult r) <0x37e6e50 + 0x000eb> in <filename unknown>:0
  --- End of inner exception stack trace ---
  --- End of inner exception stack trace ---
  at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) <0x1e97358 + 0x00187> in <filename unknown>:0
  at System.Net.HttpWebRequest.GetResponse () <0x1e8c208 + 0x0004c> in <filename unknown>:0
  at MainClass.Main (System.String[] args) <0x727f88 + 0x00082> in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.Net.WebException: Error: SendFailure (Error writing headers) ---> System.Net.WebException: Error writing headers ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
  at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (IAsyncResult asyncResult) <0x37e5fb8 + 0x000e3> in <filename unknown>:0
  at Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord (IAsyncResult ar, Boolean ignoreEmpty) <0x37e5f10 + 0x0001f> in <filename unknown>:0
  at Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (IAsyncResult result) <0x37da130 + 0x0019b> in <filename unknown>:0
  --- End of inner exception stack trace ---
  at System.Net.WebConnection.EndWrite (System.Net.HttpWebRequest request, Boolean throwOnError, IAsyncResult result) <0x37e7408 + 0x00183> in <filename unknown>:0
  at System.Net.WebConnectionStream+<SetHeadersAsync>c__AnonStorey1.<>m__0 (IAsyncResult r) <0x37e6e50 + 0x000eb> in <filename unknown>:0
  --- End of inner exception stack trace ---
  --- End of inner exception stack trace ---
  at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) <0x1e97358 + 0x00187> in <filename unknown>:0
  at System.Net.HttpWebRequest.GetResponse () <0x1e8c208 + 0x0004c> in <filename unknown>:0
  at MainClass.Main (System.String[] args) <0x727f88 + 0x00082> in <filename unknown>:0

mozroots --import --ask-remove也无济于事,无论如何都会抛出异常。

我还有一些其他 HTTPS 域也失败了:

  • http s://christian.panton.org
  • http s://penny-arcade.com
  • http s://rigeligtsmor.dk

而且我似乎无法找到为什么这些域失败的模式,即使我正在接受所有内容。

我查看了http://www.mono-project.com/docs/faq/security/http://www.mono-project.com/archived/usingtrustedrootsrespectfully/ 并在网上搜索了它,但到目前为止没有成功。

我最接近的是这个 http://stackoverflow.com/questions/9733750/mono-certificate-issue-with-https-httpwebrequest,但这是在 *nix 而不是 OSX 中。类似的帖子 http://answers.unity3d.com/questions/792342/how-to-validate-ssl-certificates-when-using-httpwe.html 和 http://stackoverflow.com/questions/4926676/mono-webrequest- https 失败

这个小程序在 Windows 上运行良好,那是因为 Windows 拥有我需要的所有根证书。

也许你们中的一些人知道这个问题的解决方案,但我有一种感觉,没有人知道如何解决这个问题。

【问题讨论】:

  • Mono 版本 Mono JIT 编译器版本 4.2.2 (explicit/996df3c Wed Jan 20 00:19:48 EST 2016) 版权所有 (C) 2002-2014 Novell, Inc、Xamarin Inc 和贡献者。 www.mono-project.com TLS:正常 SIGSEGV:altstack 通知:kqueue 架构:x86 已禁用:无 杂项:softdebug LLVM:是(3.6.0svn-mono-(分离/a173357)GC:sgen

标签: c# ssl mono certificate x509certificate


【解决方案1】:

您列为失败的域都需要Server Name Indication (SNI)。我的猜测是您的 Mono 未知版本 尚不支持 SNI。如果是这种情况,仅添加更多 CA 证书将无济于事,因为此问题与证书验证无关。

根据this bugreport,Mono 至少应该从 3.0.10 版本开始支持 SNI,但在 2.x 中不支持,因此您可以检查您正在运行的版本。

【讨论】:

  • 在我的帖子中添加了单声道版本作为评论
  • @memborg:谢谢。这个版本的 Mono 应该支持 SNI。但是由于所有这些域的共同特征是如果没有使用 SNI,它们就会中断,我仍然建议进行数据包捕获,以查看 ClientHello 是否真的包含服务器名称扩展,以及它是否包含主机的预期名称(以及不是不同的名称或 IP 地址)。由于您没有在发出请求的位置显示代码,因此那里也可能有问题,这使得无法使用 SNI(例如使用 SSL 3.0)
  • 我确实提供了我如何测试域的示例源。这是第一个代码块。
  • 经过一番谷歌搜索后,我偶然发现了这篇文章:tirania.org/blog/archive/2015/Aug.html,总而言之,我似乎必须再等一会儿才能在 OSX 上获得完整的 TLS 堆栈
  • @memborg:您没有提供任何可以看到您使用的 URL/主机名的源代码部分。主机名是 SNI 的重要组成部分,即如果不提供正确的主机名,任何 SNI 都不会成功。至于更完整的 TLS 堆栈 - 我不确定,它没有说明那里的 SNI。
猜你喜欢
  • 2023-03-24
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 2020-10-03
  • 2018-03-17
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
相关资源
最近更新 更多