Bypass invalid SSL certificate errors .Net / c# - c#

I've got a development system which I'm trying to get to communicate to a third-party secure web service.
The third party have provided me with a certificate which I've imported locally. I've made sure the certificate is added to the 'Trusted Root Certification Authorities' store. It seems to have imported correctly, as if I go Chrome and try to access one of the service urls mentioned in the web service WSDL file I firstly get a popup asking to me to confirm which certificate to use (there's only the one option) and it then lets me through. However, if I then use the same WSDL file to create a service reference in Visual Studio, and make a call to one of the services in my code, I get an error saying 'Could not establish secure channel for SSL/TLS with authority'.
Ideally I would get VS to acknowledge the cert when I'm making the webservice call, but seeing as this is a development system I'm also happy to ignore the SSL errors for the time being.
To this end I've added the following to my code, along with variations on the protocols I'm specifying (e.g. only specifying SSL3, taking out SSL3 etc):
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
But no matter what I do I still get the SSL error when I try to make the service call.
If anyone has any suggestions on how to get VS to accept the certificate is present (as Chrome seems to do) or, alternatively, how to get the code to ignore the SSL error for now, so I can proceed with development, it'd be much appreciated.

Related

Is this the correct solve for CERTIFICATE_VERIFY_FAILED exception?

So I'm currently making an Xamarin.Android app, and for a while now it has used my REST API that I made to communicate with data back and forth.
However I recently switched my SSL certificate over to LetsEncrypt which caused the following exception when trying to communicate with my API from my app:
Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
Which I assume means it didn't get verified correctly. I found the following snippet below which verifies the request from my domain only and passes it through, and this works.
However my question is. Is this secure? Could this potentially lead to a Man in the middle attack, or am I ok?
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicy) =>
{
if (sslPolicy == SslPolicyErrors.None)
return true;
if (sslPolicy == SslPolicyErrors.RemoteCertificateChainErrors &&
((HttpWebRequest)sender).RequestUri.Authority.Equals("MY_API_DOMAIN"))
return true;
return false;
};
Your way to solve this is definitely not secure: you are essentially accepting arbitrary certificates as long as the request is for a specific domain in the URL. This means a man in the middle attacker could simply intercept all traffic to this specific server, present you with his own fake certificate and sniff or even modify the data without your application noticing.
If your server works without problems with a browser it is more likely that your application/system either does not trust the Let's Encrypt CA or (more likely) that your server is setup improperly and does not send a required intermediate certificate. Please check the server against SSLLabs and look for problems like incomplete chain.
I am posting this albeit a tad late after the above answer. In my case, my cert passed the checks - even some Android devices worked but the issue was a server issue despite getting passing marks for certificate installation.
In the case of the server configuration, you must support "forward secrecy" Otherwise you will get the error above on some Android devices while others work.
Hope this helps someone.

Ignore SSL self signed certificate errors Restful httpclient

I have done tons of searching and reading on this, there are so many different ways to achieve this. However, things have changed a bit since a lot of the posts. Ultimately, I am using a UWP (10586 minimum target) app. I have wrapped my httpclient code into a .net standard library which my UWP app consumes. However, because of the 10586 SDK version, my .net standard library must be 1.4 or lower.
I need to post json to a web service in a RESTful way. Tjis web service uses SSL but has a self signed certificate. So, I get certificate errors. I simply want to ignore them so I can make my calls. Using 3rd party web service test utility (Postman), I have confirmed the calls will work if SSL errors are simply ignored.
Based on my UWP and .net standard setup, I cannot use the X509 namespace to ignore SSL errors. This is one method but X509 is not available.
So, this looked most promising: https://blog.roushtech.net/2016/12/20/ignoring-ssl-certificate-errors-net-core-httpclient/
It has no compiler errors, but at runtime I get a "platform not supported" exception.
Is there any way to work around all of this given my configurations?
EDIT: The exact snippet I am using that seems to be the supported method in the future but gives platform error on UWP is the same in the link I copied above. For reference, this is what I am doing:
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message,
cert, chain, errors) => { return true; };
using (var client = new HttpClient(httpClientHandler))
{
// Make request here.
}
}
Also, yes my code does work with non ssl (http) calls. It had been working fine for some time until I needed to access a new/different web service which is configured as ssl.
Thanks!!!

Override HTTPS certificate

I am using a URL to connect with a web service using SOAP. Apparently the URL does not have a correct https protocol and if I want to access it via browser, I need to accept the 'risk' this connection has.
My problem starts when I want to access in programmatically. When I try to send a SOAP POST request, the connection is closed and an exception is caught.
"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
Apparently this problem was common, and a lot of resources could be found, this and this being the most upvoted.
When i tried this part of code:
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
not only the connection did not work, but now I am given a:
"The remote server returned an error: (500) Internal Server Error."
Now my question is. The code above switches the protocol from https to http?
If not what does this line of code really do?
I don't know if this will be your answer, but as it is not appropriate for a comment...
Do not bypass certificate validation. You probably only need to set the correct version of TLS. You can experiment to find the highest version supported by using one at time instead of OR'ing them together.:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12
If that doesn't work you may need to obtain a certificate, either the one used by the service or one higher in the certificate chain.

HTTPWebRequest Could not create SSL/TLS secure channel

I am trying to call a Web API using HttpWebRequest(Console Application).
To upload the file, I am using the code snippet provided by #Cristian Romanescu ont this question Upload files with HTTPWebrequest (multipart/form-data)
If I set the req.ProtocolVersion as HttpVersion.Version10,I get Bad request when I try to do req.GetResponseStream().
If i set the req.ProtocolVersion as HttpVersion.Version11,I get Could not create SSL/TLS secure channel. when i try to do req.GetResponseStream().
If tried to post the data using POSTMAN, but even Postman says Could not get any response".
If I try to hit the URL using IE-11 I get HTTP 404.[I know i am not posting the actual file], but Chrome displays the custom/appropriate error message.
I tried the solutions already provided on stackoverflow, but unfortunately they do not solve my problem.
Thankyou.
Which solution you have tried? It's worth trying the following if you haven't already - write following before you actually invoke the service:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
Two things that I was doing wrong.
The Server wanted date in yyyy-MM-ddTHH:mm:ss, I was providing the date in yyyy-MM-ddTHH:mm:ss.ssss Format(DateTime.UtcNow.ToString("o")). This was the cause of Could not create SSL/TLS secure channel
The server wanted the parameters in request body as well. I had passed the parameters only as query string. This was the cause of HTTP 404
In the process, I had asked a guy outside my team to help. He had asked me to see if there were any SSL related errors. To do this he asked me to add
System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications); and define AcceptAllCertifications, which was not the case. So to resolve the issue, I had to take care of the things mentioned above.
Try to create self signed certificate from your server and add it to your client machine.
Create self signed certificate (Server side)
Import self signed certificate (Client side)

Using WCF service in MonoTouch with Authentication

I am using a WCF service client generated by slsvcutil form Silverlight toolkit version 4. I've also tried version 3 with the same problems. When I use a client instance running on http with no user credentials it runs without problems. But I need to switch to https for productive servers and send user credentials that are hardcoded for my application. I use the following code for that:
var binding = new BasicHttpBinding (BasicHttpSecurityMode.TransportCredentialOnly);
var endpoint = new EndpointAddress (AppSettings.FlareEndPoint);
_service = new TopicAnalystAPIClient(binding, endpoint);
_service.ClientCredentials.UserName.UserName = "xxx";
_service.ClientCredentials.UserName.Password = "xxx";
When I call a method on that service pointing to http with no authentication it works. When I use the this code against http/https with the credential I get "There was an error on processing web request: Status code 401(Unauthorized): Unauthorized" exception. I've checked that the credentials are correct, I am able to open the service reference in my browser. I've also tried several combinations of http/https and SecurityMode value. I've also tried it on four different servers always with the same result.
What can be the problem?
A lot of permutations are possible. BasicHttpSecurityMode.TransportCredentialOnly should be usable without SSL [1] using HTTP itself. This means the server will send one (or more) authentication method(s) to the client (e.g. basic, digest, ntlm) and Mono (including MonoTouch) should be providing support for the most of them.
It is possible that the linker (if used) removes one of them. In that case you could try building and testing without linking (or skip linking of System.Net.dll).
It's also possible that the authentication method that the serve insist on is not supported. You could find which one is used by running a network trace (e.g. wireshark) or, maybe, it will show up in more details in the server log (along with the 401 error).
[1] http://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpsecuritymode%28v=vs.95%29.aspx

Categories