2

Related: Make Https call using HttpClient

Here's an example that illustrates how I'm doing Web Service calls:

class Program
{
    static void Main(string[] args)
    {
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

        var client = new HttpClient();
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(@"text/javascript") { CharSet = "utf-8" });

        client.BaseAddress = new Uri("https://...");

        HttpResponseMessage msg = client.GetAsync("jobs").Result;

        string json = msg.Content.ReadAsStringAsync().Result;

        // Deserialize this for later use
    }
}

As I understand it from the answers there, as well as from this, this will establish a secure TLS connection and messages will be encrypted.

My understanding from the Wikipedia description of TLS 1.2 as well as the previously-mentioned documents and Q&A is that it uses public-key cryptography to authenticate the identity of the server and AES to do the exchange. However, Wikipedia's vague as to the exact details (e.g. the AES key size and mode, how the key is exchanged and stored, etc.). How is this handled in HttpClient? What AES key size and mode is it using (if it is, in fact, using AES), how does it do the key exchange, and how does it store the key?

  • 1
    Which exact encryption algorithms and protocols are used depends on the server. It is not guaranteed to make a TLS connection, it could also be an SSL connection (a predecessor of TLS). If your question is which exact algorithms are used, then the answer is: It depends. – Lukas Boersma Feb 02 '18 at 15:23
  • 2
    Both the symmetric & asymmetric algorithms used and their key lengths are negotiable, Good explanation: https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.1.0/com.ibm.mq.doc/sy10660_.htm & the requirements of this negotiation for TLS 1.2 (i.e. the minimum) is here https://tools.ietf.org/html/rfc5246#appendix-A.5 – Alex K. Feb 02 '18 at 15:24
  • I believe the client and server involved in any specific transaction can specify which exact method they support and want to use, within the ones allowed by the specification. https://www.ietf.org/rfc/rfc5246.txt – ADyson Feb 02 '18 at 15:24
  • 2
    The answer to almost all of this is that it's negotiated between server and client, based on preferences configured in the OS, and constrained by the rules of the protocol. `HttpClient` does very little of this itself; it defers to `schannel`, the native security package. (Assuming .NET on Windows.) – Jeroen Mostert Feb 02 '18 at 15:25
  • @LukasBoersma Good points - I do, in fact, occasionally get an error saying that it couldn't establish a TLS/SSL connection (the error's usually resolved with a retry, though), so it seems like it's genuinely making a secure connection. Should I try to ask the API vendor for details on what the server's doing, or is there a way to find out what's happening on my end without having to check with them? – EJoshuaS - Stand with Ukraine Feb 02 '18 at 15:27
  • In .Net you can enable Tracing for Http/WebClient requests, this includes a lot of the TLS setup/teardown info & and logs any problems. – Alex K. Feb 02 '18 at 15:28
  • `HttpClient` does not itself handle encryption, being just a wrapper around unmanaged Win32 SSPI API. You can enable .NET network tracing and see most of what's happening on your end, including key exchange and cipher package negotiation. As for Wikipedia being vague on the details of TLS, it is not aimed at a technical audience. You are much better heading off to the relevant RFCs, as suggested above. – Anton Tykhyy Feb 02 '18 at 15:29
  • @AntonTykhyy Yes, I found that after I posted the comment, I just forgot to delete it. – EJoshuaS - Stand with Ukraine Feb 02 '18 at 15:36
  • @AlexK. or AntonTykhyy - enabling that helped me figure this out, thanks for the advice - if you add that as an answer, I'd definitely be glad to upvote/accept. – EJoshuaS - Stand with Ukraine Feb 02 '18 at 15:41
  • @AntonTykhyy I'd be glad to accept/upvote the information you provided if it's added as an answer (since enabling logging like you and AlexK. suggested solved my problem). – EJoshuaS - Stand with Ukraine Feb 02 '18 at 16:08
  • You've answered your own question, really, with some help from commenters. I think it's more appropriate for you to accept your own answer. – Anton Tykhyy Feb 03 '18 at 07:20

1 Answers1

3

To summarize the comments (as a Community Wiki answer since I'm summarizing other people's material), the content will be encrypted, but the exact details of the encryption are negotiated with the server (meaning that there's not one correct answer - it depends on configuration).

Microsoft has instructions on how to find out details here. They suggest adding the following to your App.config:

<system.diagnostics>  
    <sources>  
      <source name="System.Net" tracemode="includehex" maxdatasize="1024">  
        <listeners>  
          <add name="System.Net"/>  
        </listeners>  
      </source>  
      <source name="System.Net.Cache">  
        <listeners>  
          <add name="System.Net"/>  
        </listeners>  
      </source>  
      <source name="System.Net.Http">  
        <listeners>  
          <add name="System.Net"/>  
        </listeners>  
      </source>  
      <source name="System.Net.Sockets">  
        <listeners>  
          <add name="System.Net"/>  
        </listeners>  
      </source>  
      <source name="System.Net.WebSockets">  
        <listeners>  
          <add name="System.Net"/>  
        </listeners>  
      </source>  
    </sources>  
    <switches>  
      <add name="System.Net" value="Verbose"/>  
      <add name="System.Net.Cache" value="Verbose"/>  
      <add name="System.Net.Http" value="Verbose"/>  
      <add name="System.Net.Sockets" value="Verbose"/>  
      <add name="System.Net.WebSockets" value="Verbose"/>  
    </switches>  
    <sharedListeners>  
      <add name="System.Net"  
        type="System.Diagnostics.TextWriterTraceListener"  
        initializeData="network.log"  
      />  
    </sharedListeners>  
    <trace autoflush="true"/>  
  </system.diagnostics>

This results in highly detailed logs about the connection (including very specific details about what encryption schemes are being used). For example, I was able to discover that the AES key length is 128 bits, that they're using Elliptic Curve Diffie-Hellman for the key agreement, and various other details of the security.