简体   繁体   中英

Using HttpClient & HttpWebRequest for Https TLS1.2

In Console Application, while trying to hit the "https" Endpoint configured with TLS 1.2.

In C# While using HttpClient I am getting the success response from endpoint

       HttpClient httpClient = new HttpClient();

        //specify to use TLS 1.2 as default connection
        System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;

        httpClient.BaseAddress = new Uri("HTTPSENDPOINT");
        httpClient.DefaultRequestHeaders.Accept.Clear();
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var content = new StringContent("POSTDATA");
        var task = httpClient.PostAsync("/Token", content);

        task.Wait();

        Console.WriteLine(task.Result.Content.ReadAsStringAsync().Result.ToString());

But when using HttpWebRequest

       var request = (HttpWebRequest)WebRequest.Create("HTTPSENDPOINT/Token");
       var postData = "POSTDATA";
        var data = Encoding.ASCII.GetBytes(postData);

        System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = data.Length;

        using (var stream = request.GetRequestStream()) // Getting Error in GetRequestStream() method call
        {
            stream.Write(data, 0, data.Length);
        }

        var response = (HttpWebResponse)request.GetResponse();

        var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

I am getting below error

The request was aborted: Could not create SSL/TLS secure channel.

Please guide me what I am doing wrong while using HttpWebRequest?

You need to set the SecurityProtocol property before calling WebRequest.Create method.

Update:

Let me add some details that explain why this should be correct.

Having a look at the source code of WebRequest.Create(string) method from referencesource.microsoft.com .

The return value is:

return Create(new Uri(requestUriString), false);

so now, Let's take a look at Create(Uri, bool) method, it returns some object from WebRequestPrefixElement.Creator.Create(Uri) .

Creator is a property inside of WebRequestPrefixElement and it's of type IWebRequestCreate . In your case, IWebRequestCreate will be an HttpRequestCreator object.

Looking at the code of HttpRequestCreator.Create method:

public WebRequest Create( Uri Uri ) {
    //
    // Note, DNS permissions check will not happen on WebRequest
    //
    return new HttpWebRequest(Uri, null);
}

Finally, Let's look at that HttpWebRequest constructor. You'll see a long code there, but really what is important is this line:

SslProtocols = (SslProtocols)ServicePointManager.SecurityProtocol;

so the SecurityProtocol value is assigned to a property called SslProtocols . So, it's obvious now that SecurityProtocol is used and kind of saved to the HttpWebRequest object when you call Create method, so changing SecurityProtocol after calling Create will not change the protocol used by the HttpWebRequest object.

Your question seem really close to this problem The request was aborted: Could not create SSL/TLS secure channel

I noticed that they had a problem with not adding SecurityProtocolType.Ssl3 with the other ones you already added. Try to implement the enum protocol as what the top rated answer did.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM