我在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
答案 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
}
}