某些 HTTPS 域在单声道中失败

Some HTTPS domains fail in mono

我有一些 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://www.mono-project.com/docs/faq/security/ or http://www.mono-project.com/archived/usingtrustedrootsrespectfully/ 并在网上搜索了它,但到目前为止没有找到任何结果。

我最接近的是这个 *nix 而不是 OSX。类似 post http://answers.unity3d.com/questions/792342/how-to-validate-ssl-certificates-when-using-httpwe.html 和

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

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

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

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