How do I use WebRequest to access an SSL encrypted site using HTTPS?
Asked Answered
P

4

124

I'm writing a program that reads content from a user provided URL. My problem is in the code that goes something like this:

Uri uri = new Uri(url);
WebRequest webRequest = WebRequest.Create(uri);
WebResponse webResponse = webRequest.GetResponse();
ReadFrom(webResponse.GetResponseStream());

And this is breaking if the provided url is an https:// URL. Can anyone help me with changing this code so that it will work with SSL encrypted content. Thanks.

Pylorus answered 18/2, 2009 at 12:11 Comment(0)
F
185

You're doing it the correct way but users may be providing urls to sites that have invalid SSL certs installed. You can ignore those cert problems if you put this line in before you make the actual web request:

ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);

where AcceptAllCertifications is defined as

public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
}
Fiddlededee answered 18/2, 2009 at 14:24 Comment(4)
Thanks for this answer! To avoid some useless code I used it like this: ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;Ashtonashtonunderlyne
Thanks, you helped me sir. F# makes this so easier: ServicePointManager.ServerCertificateValidationCallback <- Security.RemoteCertificateValidationCallback (fun _ _ _ _ -> true)Scanlon
I prefer += delegate { return true; }Prisage
Be aware of the potential risks associated with this approach. See https://mcmap.net/q/86882/-could-not-establish-trust-relationship-for-ssl-tls-secure-channel-soap for more information.Bordie
C
22

This one worked for me:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Chrisoula answered 5/1, 2017 at 12:1 Comment(2)
The default value is "Ssl2 | Tls". I had only had enabled Tls 1.1 and 1.2 on my server. This indeed fixed the problem! For LetsEncrypt with nginX on linux, the protocols are defined here: /etc/letsencrypt/options-ssl-nginx.confIntense
I believe this is dealing with a different issue. It's not about invalid Certs but a higher TLS versions.Vesicant
T
18

This link will be of interest to you: http://msdn.microsoft.com/en-us/library/ds8bxk2a.aspx

For http connections, the WebRequest and WebResponse classes use SSL to communicate with web hosts that support SSL. The decision to use SSL is made by the WebRequest class, based on the URI it is given. If the URI begins with "https:", SSL is used; if the URI begins with "http:", an unencrypted connection is used.

Tommi answered 18/2, 2009 at 12:20 Comment(1)
Your answer implies the code in the question should work?Rahal
A
0

As the most voted answer by @LukeDuff correctly says, it is probable that the server uses an invalid or untrusted (or self-signed, what is technically also untrusted) certificate. But the answer blindly accepts any certificate. And what's worse, even any certificate for any site, even for sites, where you expect trusted and valid certificate. That's a security flaw.

When implementing ServicePointManager.ServerCertificateValidation callback one should validate the certificate. E.g. by checking certificate's hash against a known value:

using System.Net;
using System.Net.Security;
using System.Security.Cryptography;
ServicePointManager.ServerCertificateValidationCallback +=
    (sender, certificate, chain, errors) =>
    {
        return
            (errors == SslPolicyErrors.None) ||
            certificate.GetCertHashString(HashAlgorithmName.SHA256).Equals(
                "EB8E0B28AE064ED58CBED9DAEB46CFEB3BD7ECA677...");
    };

For the X509Certificate.GetCertHashString overload that takes HashAlgorithmName.SHA256, you need .NET 4.8. On older versions use the parameter-less overload that returns an SHA-1 hash.


Based on Is it safe to test the X509Certificate.Thumbprint property when you know an invalid certificate is safe?

For VB.NET version of the code, see Accept self-signed TLS/SSL certificate in VB.NET.

Annapolis answered 31/3, 2021 at 6:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.