Mono https webrequest failed with an authentication or decryption error

I am making a simple REST client for use in my C # applications. On .net on Windows It works great with http: // and https: // connections. In mono 2.6.7 (also verified with 2.8 with the same results) on Ubuntu 10.10 only http: // works. https: // connections throw this exception in the request.GetResponse () method:

Unhandled Exception: 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 at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.validateCertificates (Mono.Security.X509.X509CertificateCollection certificates) [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.ProcessAsTls1 () [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.Handshake.HandshakeMessage.Process () [0x00000] in <filename unknown>:0 at (wrapper remoting-invoke-with-check) Mono.Security.Protocol.Tls.Handshake.HandshakeMessage:Process () at Mono.Security.Protocol.Tls.ClientRecordProtocol.ProcessHandshakeMessage (Mono.Security.Protocol.Tls.TlsStream handMsg) [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 --- End of inner exception stack trace --- at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 --- End of inner exception stack trace --- at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0 

I could not find a way to fix this. Does anyone know why this is happening and how to fix it?

Again, this is only a failure in Mono, .NET does not cause problems with establishing a connection.

here is the call code:

 public JToken DoRequest(string path, params string[] parameters) { if(!path.StartsWith("/")) { path = "/" + path; } string fullUrl = url + path + ToQueryString(parameters); if(DebugUrls) Console.WriteLine("Requesting: {0}", fullUrl); WebRequest request = HttpWebRequest.CreateDefault(new Uri(fullUrl)); using(WebResponse response = request.GetResponse()) using(Stream responseStream = response.GetResponseStream()) { return ReadResponse(responseStream); } } 
+61
c # mono webrequest
Feb 07 2018-11-21T00:
source share
8 answers

I had the same issue with Unity (which also uses mono) and this post helped me solve this problem.

Just add the following line before making your request:

 ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback; 

And this method:

 public bool MyRemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { bool isOk = true; // If there are errors in the certificate chain, // look at each error to determine the cause. if (sslPolicyErrors != SslPolicyErrors.None) { for (int i=0; i<chain.ChainStatus.Length; i++) { if (chain.ChainStatus[i].Status == X509ChainStatusFlags.RevocationStatusUnknown) { continue; } chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan (0, 1, 0); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; bool chainIsValid = chain.Build ((X509Certificate2)certificate); if (!chainIsValid) { isOk = false; break; } } } return isOk; } 
+40
Oct 28 '15 at 12:37
source

The .NET Framework on Windows uses the Windows certificate store (mmc, Add / Remove Snap-Ins, Certificates) to determine whether to accept an SSL certificate from a remote site. Windows comes with a bunch of root and intermediate certificate authorities (CAs) and they are periodically updated using Windows Update. As a result, your .NET code will typically trust the certificate if it was issued by a CA or a descendant of CA in a certificate store (the most reputable commercial CAs are included).

Mono does not have a Windows certificate store. Mono has its own store. By default, it is empty (no trusted CAs by default). You need to manage your records yourself.

Take a look here:

The mozroots.exe point will force your installation to trust everyone that Firefox trusts after the default installation.

+25
Jan 22 '14 at 19:08
source

Write this line before requesting an HTTP request. it should be work.

 ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback((sender, certificate, chain, policyErrors) => { return true; }); private static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { //Return true if the server certificate is ok if (sslPolicyErrors == SslPolicyErrors.None) return true; bool acceptCertificate = true; string msg = "The server could not be validated for the following reason(s):\r\n"; //The server did not present a certificate if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable) { msg = msg + "\r\n -The server did not present a certificate.\r\n"; acceptCertificate = false; } else { //The certificate does not match the server name if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch) { msg = msg + "\r\n -The certificate name does not match the authenticated name.\r\n"; acceptCertificate = false; } //There is some other problem with the certificate if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors) { foreach (X509ChainStatus item in chain.ChainStatus) { if (item.Status != X509ChainStatusFlags.RevocationStatusUnknown && item.Status != X509ChainStatusFlags.OfflineRevocation) break; if (item.Status != X509ChainStatusFlags.NoError) { msg = msg + "\r\n -" + item.StatusInformation; acceptCertificate = false; } } } } //If Validation failed, present message box if (acceptCertificate == false) { msg = msg + "\r\nDo you wish to override the security check?"; // if (MessageBox.Show(msg, "Security Alert: Server could not be validated", // MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) == DialogResult.Yes) acceptCertificate = true; } return acceptCertificate; } 
+7
Dec 03
source

I also encounter an error.

I tried ServicePointManager.ServerCertificateValidationCallback and ServicePointManager.CertificatePolicy , but still did not work.

I am angry. build a cURL wraper. It works great for my toy project.

 /// <summary> /// For MONO ssl decryption failed /// </summary> public static string PostString(string url, string data) { Process p = null; try { var psi = new ProcessStartInfo { FileName = "curl", Arguments = string.Format("-k {0} --data \"{1}\"", url, data), RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = false, }; p = Process.Start(psi); return p.StandardOutput.ReadToEnd(); } finally { if (p != null && p.HasExited == false) p.Kill(); } } 
+3
May 30 '15 at 15:47
source

I had the same problem. When the HTTP response raises this exception, I do the following:

 System.Diagnostics.Process.Start("mozroots","--import --quiet"); 

it imports the missing certificates and the exception never happens again.

+2
Aug 11 '15 at 22:57
source

The first answer already says: Mono does not come with anything other than Windows, so initially it does not trust any certificate. So what to do?

Here is a good article on different ways to solve the problem from the point of view of developers: http://www.mono-project.com/archived/usingtrustedrootsrespectfully/

Short Description: You can:

  • ignore security issue
  • ignore the problem
  • inform the user and interrupt him
  • inform the user and give him the opportunity to continue his own risk.

The link above provides code examples for each case.

+2
Oct. 16 '15 at 23:13
source

Another solution for Unity is to initialize the ServicePointManager once to always accept certificates. This works, but obviously unsafe.

 System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate (object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) { return true; // **** Always accept }; 
+2
Feb 19 '16 at 21:03
source

You can install the Mono TLS implementation in iOS Build and everything will work fine, as described here: http://massivepixel.co/blog/post/xamarin-studio-6-certificate-unknown (although Mono TLS does not support newer versions TLS, but I have not run into a problem yet, that it is a problem).

0
Aug 03 '16 at 11:09
source



All Articles