Transport Layer Security (TLS)

PDF for offline use
Related Articles:
Related Samples:
Related APIs:
Related Links:

Let us know how you feel about this


0/250

last updated: 2017-01

Enabling TLS 1.2 in Xamarin.Android and Xamarin.iOS

Overview

Secure network communications between a mobile device and a server or another device is of critical importance to a mobile application. The responsibility for this important task falls to Transport Layer Security (TLS) protocol, also referred to as the Secure Sockets Layer (SSL). TLS uses symmetric cryptography to help identify endpoints (preventing man-in-the-middle attacks) and to ensure the integrity and privacy of the communication.

Starting with Mono 4.8, TLS 1.2 support available and provided by the BoringSSL project from Google.

It is possible for Xamarin mobile applications incorporate TLS 1.2 by using the System.Net.HttpClient API and specifying a platform-specific implementation of System.Net.HttpMessageHandler that will leverage the native API's for TLS 1.2. For this reason HttpClient should be the preferred API for Xamarin applications that require secure network communications.

By default, on Xamarin.Android and Xamarin.iOS, HttpClient will use the managed System.Net.HttpClientHandler as the default HttpMessageHandler implementation. This class is 100% managed code that supports TLS 1.0. Applications that require TLS 1.2 should use platform specific implementations of HttpMessageHandler as described in the following sections.

Requirements

This guide applies to Xamarin.Android 6.1 and Xamarin.iOS 9.8 (or higher).

It is possible that older versions of Xamarin Studio or Xamarin for Visual Studio may experience issues opening a CSPROJ file that has been created or edited with Xamarin.iOS version 9.8.

Xamarin.Android

The AndroidClientHandler class was introduced in Xamarin.Android 6.1 to provide TLS 1.2 support to Xamarin.Android applications. This class uses the native java.net.URLConnection for all HTTP connections, allowing an HttpClient instance to use any network and encryption protocols available to Android.

ℹ️

The underlying Android device must support TLS 1.2; Android 5.0 and later support TLS 1.2

There are three ways to use AndroidClientHandler in a Xamarin.Android app:

  1. Set the default HttpClientHandler for the Xamarin.Android project – Under **Project Options > Android Build, on the General tab is a setting to specify which HttpClientHandler is the default for a Xamarin.Android app:

  2. <a href="Images/tls05-xs.png"><img src="Images/tls05-xs.png"/></a>
    
    <li>**Use an instance of the new `Xamarin.Android.Net.AndroidClientHandler`** &ndash; This is a new `HttpMessageHandler` implementation specifically for Xamarin.Android. This code snippet is an example of how to explicitly for a single instance of the `HttpClient` class:</li>
    <pre>`// Android 5.0 or higher, Xamarin.Android 6.1 or higher

    HttpClient client = new HttpClient(new Xamarin.Android.Net.AndroidClientHandler ());`

    <li>**Set the `XA_HTTP_CLIENT_HANDLER_TYPE` environment variable**&ndash; This environment variable declares the default `HttpMessageHandler` class that will be used by all `HttpClient` instances:</li>
    
    <pre>`XA_HTTP_CLIENT_HANDLER_TYPE=Xamarin.Android.Net.AndroidClientHandler`</pre>
    
    <p>This environment variable is set by adding an <i>environment file</i> to the project. An environment file is a Unix-formatted plain-text file with a build action of <span class="uiitem">AndroidEnvironment</span>:
    
    <a href="Images/tls03-xs.png"><img src="Images/tls03-xs.png"/></a>

[[/ide]]

<ol>
    <li>**Set the default `HttpClientHandler` for the Xamarin.Android project** &ndash; Under **Project Properties &gt; Android Options**, on the **Advanced** tab is a setting to specify which `HttpClientHandler` is the default for a Xamarin.Android app:</li>

    <a href="Images/tls05-vs.png"><img src="Images/tls05-vs.png"/></a>

    <li>**Use an instance of the new `Xamarin.Android.Net.AndroidClientHandler`** &ndash; This is a new `HttpMessageHandler` implementation specifically for Xamarin.Android. This code snippet is an example of how to explicitly for a single instance of the `HttpClient` class:</li>
    <pre>`// Android 5.0 or higher, Xamarin.Android 6.1 or higher

HttpClient client = new HttpClient(new Xamarin.Android.Net.AndroidClientHandler ());`

<li>**Set the `XA_HTTP_CLIENT_HANDLER_TYPE` environment variable**&ndash; This environment variable declares the default `HttpMessageHandler` class that will be used by all `HttpClient` instances:</li>

    <pre>`XA_HTTP_CLIENT_HANDLER_TYPE=Xamarin.Android.Net.AndroidClientHandler`</pre>

    <p>This environment variable is set by adding an <i>environment file</i> to the project. An environment file is a Unix-formatted plain-text file with a build action of <span class="uiitem">AndroidEnvironment</span>:

    <a href="Images/tls03-vs.png"><img src="Images/tls03-vs.png"/></a>    
</ol>

Please see the Xamarin.Android Environment guide for more details about environment variables and Xamarin.Android.

Xamarin.iOS / Xamarin Mac

There are three ways that a Xamarin.iOS application can leverage the features of TLS 1.2:

  1. Use the Apple TLS Stack – Changing the TLS provider to the native Apple TLS.
  2. Set the default HttpClientHandler for the Xamarin.iOS project – Select the default HttpMessageHandler to be used by a Xamarin.iOS application.
  3. Programmatically instantiate the HttpClient with a HttpMessageHandler – programmatically instantiate a HttpClient and specify the HttpMessageHandler to be used for that object.

Apple introduced App Transport Security (ATS) in iOS 9. ATS enforces secure connections between internet resources (such as a mobile app and a server) using TLS 1.2. App Transport Security is enabled by default in apps built for iOS 9 and OS X 10.11 (El Capitan), all connections using NSUrlConnection, CFUrl or NSUrlSession will be subject to ATS security requirements. If your connections do not meet these requirement, they will fail with an exception. Please see Xamarin's App Transport Security guide for more details.

Using the Apple TLS Stack

It is possible to switch from the default Mono TLS stack (which only supports TLS 1.0) to the the Apple TLS stack (which supports TLS 1.2). The Apple TLS stack uses native code and will offer the best performance and will also rely on the default iOS settings for TLS.

In Xamarin Studio, the TLS stack may be set in the Project Options of a Xamarin.iOS project:

In Visual Studio (and optionally Xamarin Studio) it is possible to specify which TLS provider a Xamarin.iOS should use by providing the the `--tls-provider` command line parameter to **mtouch**:

ArgumentDescription
`--tls-provider=legacy`Use the Mono TLS stack.
`--tls-provider=appletls`Use the Apple TLS stack.

This command line parameter is set on the Project Options > iOS Build in Visual Studio:

Changing the TLS stack in this fashion will provide TLS support to all APIs based on System.Net.WebRequest, such as HttpClient and WebClient.

HttpClient

Instances of the HttpClient class can be configured to use TLS 1.2 features, depending on the HttpMessageHandler instance that is provided when a HttpClient object is instantiated. There are three handlers for Xamarin.iOS, however only two of them are TLS 1.2 compliant:

  • HttpClientHandler – This is the default HttpMessageHandler, and only supports TLS 1.0. It is 100% managed code and therefore the most compatible.
  • CFNetworkHandler – A wrapper around the native CFNetwork APIs. Supports TLS 1.2. Available in iOS 6 and higher.
  • NSUrlSessionHandler – A wrapper around the native NSURLSession API. Supports TLS 1.2. Available in iOS 7 and higher.

Both CFNetworkHandler and NSUrlSessionHandler are similar in overall functionality; they are managed wrappers around the native iOS code that will:

  • Use the underlying native code for network communications and transport.
  • Result in a smaller executable.
  • Offer improved network performance.
  • Use the underlying iOS queues and threads, thereby not block the main thread.
  • Honor the underlying iOS defaults for TLS settings.
  • On iOS 9 and higher, Xamarin.iOS applications must use https unless http has be explictly allowed in Info.plist. Please see the Configuring ATS Options section of the App Transport Security guide for more details.

In Xamarin Studio, it is possible to specify the `HttpClientHandler` implementation a Xamarin.IOS application should use can in the Project Options:

In Visual Studio, (and optionally Xamarin Studio, it is possible to set the default `HttpMessageHandler` for the entire application using the `--http-message-handler` command line parameter for **mtouch**:

ArgumentDescription
`--http-message-handler=HttpClientHandler`Use managed `HttpClientHandler` provided by Mono.
`--http-message-handler=CFNetworkHandler`Use the `CFNetworkHandler`.
`--http-message-handler=NSUrlSessionHandler`Use the `NSUrlSessionHandler`.

This command line parameter is set on the Project Options > iOS Build in Visual Studio, as:

Programmatically Setting the HttpMessageHandler

A third option is to instantiate a HttpClient and inject the desired HttpMessageHandler through the constructor, as demonstrated in these code snippets:

// This will use the default message handler for the application; as
// set in the Project Options for the project.
HttpClient client = new HttpClient(); 

// This will create an HttpClient that explicitly uses the CFNetworkHandler
HttpClient client = new HttpClient(new CFNetworkHandler());

// This will create an HttpClient that explicitly uses NSUrlSessionHandler
HttpClient client = new HttpClient(new NSUrlSessionHandler());

This makes it possible to use a different HttpMessageHandler from what is declared in the Project Options dialog.

Known Issues

This section will cover known issues with TLS support in Xamarin.iOS.

Project failed to load with error "Requested value AppleTLS wasn't found"

Xamarin.iOS 9.8 introduced some new settings contained the .CSPROJ file for a Xamarin.iOS application. These changes may cause problems when the project is opened with older versions of Xamarin.iOS. The following screenshot is a example of the error message that may be displayed in this scenario:

This error is caused by the introduction of the MtouchTlsProvider setting to the project file in Xamarin.iOS 9.8. If it is not possible to update to Xamarin.iOS 9.8 (or higher), the work around is to manually edit the .CSPROJ file application, remove the MtouchTlsprovider element, and then save the changed project file.

The following snippet is an example of what the MtouchTlsProvider setting may look like inside a .CSPROJ file:

<MtouchTlsProvider>Default</MtouchTlsProvider>

Summary

This guide discussed how to implement Transport Layer Security in Xamarin.Android and Xamarin.iOS applications.

Xamarin Workbook

If it's not already installed, install the Xamarin Workbooks app first. The workbook file should download automatically, but if it doesn't, just click to start the workbook download manually.