1

My application connects to an external service to receive data. The external service is updating their security protocol to exclude TLS 1.0 and below. I have already added the following to Global.asax:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 |
                                       SecurityProtocolType.Tls11 |
                                       SecurityProtocolType.Tls;

However, I would like to verify that I am connecting to the external service via Tls 1.1 or higher.

Is it possible to see the security protocol being used in a connection? I would suspect it's stored somewhere in one of the properties of the request/response objects.

var request = (HttpWebRequest) WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/json";
request.Headers["Device-Token"] = deviceId;
var response = request.GetResponse().GetResponseStream();

Does anyone know where I can find this information? Or is there a better way to verify the security protocol being used?


EDIT

To adhere to better practice (as per Jf Beaulac's comments), the code for setting the connection protocol was changed to:

ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | 
                                        SecurityProtocolType.Tls11;
JED
  • 1,538
  • 2
  • 19
  • 47
  • While `HttpWebRequest` gained the `ServerCertificateValidationCallback` event in .NET 4.5 which lets you examine the certificate, it still lacks a way to obtain information about the underlying TLS network connection. – Dai May 25 '18 at 15:43
  • @Dai - so I should just cross my fingers and hope for the best?<> I have about 300 customers that use this data regularly. I'd really hate to have any lapse in connectivity when the external service makes their change next month. – JED May 25 '18 at 15:57

2 Answers2

0

If you simply wanna check which level the connection is actually using, juste remove the unwanted protocols when you set the value of SecurityManager.SecurityProtocol. If the connection uses the protocols that you excluded an Exception will occur.

Note that specifying the SecurityProtocol the way you do in Global.asax should be avoided and is bad practice. see the remarks on MSDN:

https://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.securityprotocol%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

Jf Beaulac
  • 5,206
  • 1
  • 25
  • 46
  • I am under the impression that it is bad practice to explicitly use **a single** security protocol. In my case, I am giving the app a list of security protocols to use. Since my app is targeting .NET 4.5 (which I intend to change in the near future), the highest security protocol that is supported by default is Tls 1.0. If I want to connect over a higher level security protocol, I have to explicitly state the `SecurityManager.SecurityProtocol` to include Tls 1.1 and Tls 1.2. – JED May 25 '18 at 16:08
  • Its bad practice to set this manually at all, you should let the system on which the code is running handle this. My suggestion to remove protocols to see which one is actually used is only valid for debugging purposes, not production code. Note that while setting the value manually is bad, removing protocols you dont want is OK. See answer by Scott in this SO question: https://stackoverflow.com/questions/28286086/default-securityprotocol-in-net-4-5 – Jf Beaulac May 25 '18 at 18:36
  • Fair enough. I did not realize that the `|=` operator was a thing. – JED May 29 '18 at 12:22
0

I found that PayPal is also in the process of changing their security settings.

PayPal provides an API endpoint (https://tlstest.paypal.com/) for testing your application's security protocol to ensure that it supports TLS 1.2 and HTTP/1.1.

Here's how I tested this:

MVC Application

./Global.asax.cs

...
protected void Application_Start()
{
    ...

    // Add Tls 1.1 and 1.2 to security protocol list (without removing defaults)
    ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls1.2 | SecurityProtocolType.Tls1.1
}
...


./Controllers/TestConnection.cs

using System;
using System.IO;
using System.Net;
using System.Web.Http;

namespace MyMVCApplication.Controllers
{
    public class TestConnectionController : ApiController
    {
        public string Get()
        {
            var url = new Uri("https://tlstest.paypal.com/");
            var request = (HttpWebRequest) WebRequest.Create(url);
            request.Method = "GET";
            request.ContentType = "application/json";

            var response = request.GetResponse().GetResponseStream();
            if (response != null)
            {
                string output;
                using (var reader = new StreamReader(response))
                {
                    output = reader.ReadToEnd();
                }

                return output;
            }

            return null;
        }
    }
}



After running the application, you can connect to it locally (I did it using PowerShell) and receive a response from the PayPal endpoint.

PowerShell

$url = "http://localhost:60023/api/TestConnection"
Invoke-WebRequest -Uri $url -Headers @{Authorization = "Basic $credentials"} | ConvertFrom-Json

If you have added ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 to Application_Start() in Global.asax.cs, you will receive the confirmation message PalPal_Connection_OK

If your connection does not support TLS 1.2 or HTTP/1.1, you will receive a 400 error.

For more information, please visit https://www.paypal-notice.com/en/TLS-1.2-and-HTTP1.1-Upgrade/

JED
  • 1,538
  • 2
  • 19
  • 47