25

When I execute the following code

System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => {
    return true;
};
var webClient = new WebClient();
var s = webClient.DownloadString("https://jtlplugins.x-volution.de/api.php?apikey=yS5VS7OiG1ukiIqLzCSYuFCjeF1qSskKOQeCtVxh&do=pruefe_app&cappid=123&chardwareid=DC0D-BFEA-6F79-58DE-21E9-BA3A-B288-C46F&clizenzschluessel=123");

I always get a System.Net.WebException: Can not create SSL/TLS secure channel

When I execute this

https://jtlplugins.x-volution.de/api.php?apikey=yS5VS7OiG1ukiIqLzCSYuFCjeF1qSskKOQeCtVxh&do=pruefe_app&cappid=123&chardwareid=DC0D-BFEA-6F79-58DE-21E9-BA3A-B288-C46F&clizenzschluessel=123

for example direct in Firefox or Internet Explorer, it works and give back a result.

What should I do that this is also executed with my code like in the browser?

I have read the other posts in stackoverflow about this problem - but they are not solving my problem :-(

BennoDual
  • 5,865
  • 15
  • 67
  • 153

3 Answers3

45

If you close fiddler (if you have it open) and add the following the exception should go away

ServicePointManager.Expect100Continue = true;                
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Or at least it did for me when i tried your code like so

try
{
     ServicePointManager.Expect100Continue = true;                
     ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

     ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

     var webClient = new WebClient();

     var s = webClient.DownloadString("https://jtlplugins.x-volution.de/api.php?apikey=yS5VS7OiG1ukiIqLzCSYuFCjeF1qSskKOQeCtVxh&do=pruefe_app&cappid=123&chardwareid=DC0D-BFEA-6F79-58DE-21E9-BA3A-B288-C46F&clizenzschluessel=123");

     MessageBox.Show("Result" + s);
}
catch(Exception ex)
{ 
  MessageBox.Show(ex.Message); 
}
  • Insecure code warning - Even though i am assuming you already know this and is not why your were getting a WebException with your code, I am adding a warning for potential future readers in the decades following the original posting of this question. The code:

    System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => { return true; };

Will ignore any certificate validation errors and therefor by definition is not exactly secure. Please see the question C# Ignore certificate errors?

kmcnamee
  • 5,097
  • 2
  • 25
  • 36
  • the line `ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };` is unsafe – ympostor Oct 30 '17 at 03:39
  • @ympostor Yes I believe that was assumed by the OP back when they originally posted the question (see their lambda expression in the original question). The question is more why is this code throwing an WebException, which adding the missing properties resolves. As such I have added a warning to future readers... PS thanks for the down vote... – kmcnamee Oct 30 '17 at 12:51
  • I have tried all of these solutions, with the following code: ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; The strangest thing is, it works on my dev environment, but not live. Any ideas? – Mike Aug 01 '22 at 13:13
6

Below is an inheritance WebClient class which resolve a lot of general problems like this...

using System;
using System.Net;
namespace YourProgram.Web
{
    public class WebClient : System.Net.WebClient
    {
        public WebClient()
        {
            ServicePointManager.Expect100Continue = true;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            this.container = new CookieContainer();
        }
        public WebClient(CookieContainer container)
        {
            this.container = container;
        }

        public CookieContainer CookieContainer
        {
            get { return container; }
            set { container = value; }
        }

        private CookieContainer container = new CookieContainer();

        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest r = base.GetWebRequest(address);
            var request = r as HttpWebRequest;
            if (request != null)
            {
                request.CookieContainer = container;
            }
            return r;
        }

        protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
        {
            WebResponse response = base.GetWebResponse(request, result);
            ReadCookies(response);
            return response;
        }

        protected override WebResponse GetWebResponse(WebRequest request)
        {
            WebResponse response = base.GetWebResponse(request);
            ReadCookies(response);
            return response;
        }

        private void ReadCookies(WebResponse r)
        {
            var response = r as HttpWebResponse;
            if (response != null)
            {
                CookieCollection cookies = response.Cookies;
                container.Add(cookies);
            }
        }
    }
}

Enjoy...

MiMFa
  • 981
  • 11
  • 14
3

None of these answers work if the servers being used host vs client have mismatched or unsupported cipher suits. In my case migration from Windows 2012 R2 to 2019 was necessary.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Dmitri K
  • 634
  • 6
  • 13
  • @dimitri and what client you are using? – BennoDual Dec 07 '22 at 02:43
  • Hi, @BennoDual, client? IIS? not sure what you mean by client. I essentially have the same code in C# MVC .NET 4.8 and it did not work until I switched to 2019 server. It was due to nature of the RSS source which was very strict. – Dmitri K Dec 07 '22 at 04:20