检查WebException中的证书验证错误

时间:2013-12-12 05:13:27

标签: c# validation ssl mono httpwebrequest

我在Mono for Android上使用WebRequests,对于某些服务器,证书验证失败。我已经实现了ICertificatePolicy(因为ServerCertificateValidationCallback从未被调用过 - 可能是Android的Mono问题?)如果用户已启用接受应用程序设置中的所有证书,则返回true。如果用户禁用此设置,则在验证问题时返回false。在这种情况下,我想显示一条消息,告诉用户发生了证书验证问题。

根据Problem SSL Certificate C#,我实现了像

这样的catch块
catch (WebException we)
        {   // If SSL throws exception that will be handled here
            if (we.Status == WebExceptionStatus.TrustFailure)
                throw new Exception( "some nice message" );
        }

但事实证明这是无用的,因为状态设置为SendFailure。异常怎么能告诉我验证失败了?我应该查看InnerException并查找TlsException以检查错误代码是否为http://msdn.microsoft.com/en-us/library/system.net.icertificatepolicy(v=vs.110).aspx中列出的代码之一?

你有更好的解决方案吗?

如果我的ICertificatePolicy返回false,这是我得到的例外:

 System.Net.WebException: Error getting response stream (Write: The authentication or decryption has failed.): SendFailure ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: Invalid certificate received from server. Error code: 0xffffffff800b010a
D/KP2A    (17517):   at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.RemoteValidation (Mono.Security.Protocol.Tls.ClientContext context, AlertDescription description) [0x00000] in <filename unknown>:0
D/KP2A    (17517):   at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.validateCertificates (Mono.Security.X509.X509CertificateCollection certificates) [0x00000] in <filename unknown>:0
D/KP2A    (17517):   at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.ProcessAsTls1 () [0x00000] in <filename unknown>:0
D/KP2A    (17517):   at Mono.Security.Protocol.Tls.Handshake.HandshakeMessage.Process () [0x00000] in <filename unknown>:0
D/KP2A    (17517):   at Mono.Security.Protocol.Tls.ClientRecordProtocol.ProcessHandshakeMessage (Mono.Security.Protocol.Tls.TlsStream handMsg) [0x00000] in <filename unknown>:0
D/KP2A    (17517):   at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
D/KP2A    (17517):   --- End of inner exception stack trace ---
D/KP2A    (17517):   at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
D/KP2A    (17517):   --- End of inner exception stack trace ---
D/KP2A    (17517):   at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
D/KP2A    (17517):   at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0
D/KP2A    (17517):   at System.Net.WebClient.GetWebResponse (System.Net.WebRequest request) [0x00000] in <filename unknown>:0
D/KP2A    (17517):   at System.Net.WebClient.OpenRead (System.Uri address) [0x00000] in <filename unknown>:0

1 个答案:

答案 0 :(得分:0)

我找到的唯一解决方案是使用“ToString()”方法检查完整的ex堆栈,看看它是否包含一些文本。

    catch(WebException ex)
    {
        string fullExStack = ex.ToString();
        if (fullExStack.Contains(("System.IO.IOException: The authentication or decryption has failed.").ToLower())
            || fullExStack.Contains(("Mono.Security.Protocol.Tls.TlsException: Invalid certificate received from server.").ToLower()))

        {
            // Do Anything you need here
            // like throwing a custom exception
        }
    }