Communicating using TLS 1.2 or TLS 1.1 securely with PowerShell

6 minute read

Ever tried downloading PowerShell Core directly from GitHub and receiving The request was aborted: Could not create SSL/TLS secure channel. error message responded back?

Examples:

1
2
3
4
# An example using Invoke-WebRequest to download package from GitHub
Invoke-WebRequest `
    -Uri 'https://github.com/PowerShell/PowerShell/releases/download/v6.0.3/PowerShell-6.0.3-win-x64.msi' `
    -OutFile 'C:\Temp\PowerShell-6.0.3-win-x64.msi' ;
1
2
3
4
# An example using Invoke-RestMethod against GitHub API
Invoke-RestMethod `
    -Uri https://api.github.com/ `
    -Method Get ;

Output:

1
2
3
4
5
6
Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.
At line:1 char:1
+ Invoke-WebRequest `
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Since the technology has moved on with SSL 3.0 and TLS 1.0 being deprecated, you may be woke up with an alarming realization that your code needs updating to support the use of TLS 1.2 (Recommended) or TLS 1.1 (Minimum) in order to get them (Eg. Invoke-WebRequest, Invoke-RestMethod) to work. While some service providers (eg. GitHub) drops SSL 3.0, TLS 1.0 and TLS 1.1 in favour of only TLS 1.2 or higher.

What actually went wrong?

There is nothing particularly wrong except you might not be aware of your current Transport Layer Security protocols configuration on the environment.

In order to find out the current Transport Layer Security protocols configuration on your environment, you can obtain a list of protocols configured on your environment by using the command in PowerShell below.

1
2
# List the Security Protocol configuration
[Net.ServicePointManager]::SecurityProtocol

Output:

1
Ssl3, Tls

If your output does not have Tls12 or Tls11 representing TLS 1.2 or TLS 1.1 listed, it means that your PowerShell console will not communicate or negotiate in those Transport Layer Security protocols with the remote resource.


Top


How to enable TLS 1.2 and TLS 1.1 protocols

To overcome the communication issue with GitHub, you will need to enable TLS 1.2 protocol.

1
2
3
# Enable TLS 1.2 as Security Protocol
[Net.ServicePointManager]::SecurityProtocol = `
    [Net.SecurityProtocolType]::Tls12 ;

But if you find that you can include all Transport Layer Security protocols that are not deprecated yet, you can input them by separating each protocol with a comma (,) like below.

1
2
3
4
# Enable TLS 1.2 and TLS 1.1 as Security Protocols
[Net.ServicePointManager]::SecurityProtocol = `
    [Net.SecurityProtocolType]::Tls12,
    [Net.SecurityProtocolType]::Tls11 ;

Once you have configured the required Transport Layer Security protocol for the communication, you can try listing them to validate they have been configured and test the communication again to determine if the secure communication can be established.

1
2
3
4
5
6
7
# Validate the configured protocol(s) is/are listed
[Net.ServicePointManager]::SecurityProtocol

# Try establishing secure communication again
Invoke-RestMethod `
    -Uri https://api.github.com/ `
    -Method Get ;

Top


Understanding Transport Layer Security Protocols

Transport Layer Security protocols are actually crytographic protocols that provide communication security over the network. The primary aim is to provide privacy and data integrity between two or more machines or applications where the connection is private because of symmetric cryptography used to encrypt the data transmitted.


Top


Deprecated Transport Layer Security Protocols

Saying goodbye to SSL 2.0, 3.0 and TLS 1.0 Transport Layer Security protocols as they are considered as deprecated protocols because of vulnerabilities.

  • SSL 2.0 introduced since February 1995 and deprecated on March 2011
  • SSL 3.0 introduced since March 1996 and deprecated on June 2015
  • TLS 1.0 introduced since January 1999 and deprecated on June 2018

Top


Currently supported Transport Layer Security Protocols

These are still supported protocols that does not have any known protocol vulnerabilities during the time this blog post is published.

  • TLS 1.1 introduced since April 2006
  • TLS 1.2 introduced since August 2008

Top


Next version of Transport Layer Security Protocol

During April 2014, a draft for TLS 1.3 specification was introduced and has been revised numerous times till today.

  • TLS 1.3 introduced since April 2014

Since then at the time of this blog post, the current draft version of TLS 1.3 is at 28 superseding draft version 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 09, 08, 07, 06, 05, 04, 03, 02, 01 and 00.

If you are interested in participating in the TLS 1.3 specification, you can participate on the following GitHub TLSWG/TLS13-Spec repository.


Top


Configuring Transport Layer Security protocols for PowerShell console

Since Transport Layer Security protocols on PowerShell may be configured with just ssl (SSL 3.0) and tls (TLS 1.0) by default, you may not want to constantly manually configure the [Net.ServicePointManager]::SecurityProtocol every time you launches your PowerShell console.

This section will demonstrates on how to configure PowerShell console with Transport Layer Security protocols persistently.


Top


TLS 1.1 and TLS 1.2

To apply persistent configuration of TLS 1.1 and TLS 1.2 to your PowerShell console, you will have to define [Net.ServicePointManager]::SecurityProtocol with the appropriate [Net.SecurityProtocolType]::Tls11 (TLS 1.1) and [Net.SecurityProtocolType]::Tls12 (TLS 1.2) properties to a Microsoft.PowerShell_Profile.ps1 file.

Note: It is highly recommended to exclude SSL 3.0 and TLS 1.0 usage if your environment is up to date and only uses TLS 1.1 or TLS 1.2 Transport Layer security protocols.

1
2
3
4
5
6
7
8
9
@"
# Configure PowerShell Transport Layer Security Protocols
[Net.ServicePointManager]::SecurityProtocol = `
    [Net.SecurityProtocolType]::Tls11,
    [Net.SecurityProtocolType]::Tls12 ;
"@ | `
Out-File `
    -FilePath "$ENV:USERPROFILE\Documents\WindowsPowerShell\Microsoft.PowerShell_Profile.ps1" `
    -Append

Top


SSL 3.0, TLS 1.0, TLS 1.1 and TLS 1.2

If you have to work with legacy Transport Layer Security protocols because your internal environment have not been upgraded to compliant with the new standard yet, you can still configure your PowerShell console to include those legacy SSL 3.0 and TLS 1.0 Transport Layer Security protocols.

Note: It is still highly recommended that you upgrade your environment to support TLS 1.2 or TLS 1.1 and stop using SSL 3.0 and TLS 1.0.

1
2
3
4
5
6
7
8
9
10
11
@"
# Configure PowerShell Transport Layer Security Protocols
[Net.ServicePointManager]::SecurityProtocol = `
    [Net.SecurityProtocolType]::Ssl3,
    [Net.SecurityProtocolType]::Tls,
    [Net.SecurityProtocolType]::Tls11,
    [Net.SecurityProtocolType]::Tls12 ;
"@ | `
Out-File `
    -FilePath "$ENV:USERPROFILE\Documents\WindowsPowerShell\Microsoft.PowerShell_Profile.ps1" `
    -Append

Top


Configuring Transport Layer Security protocols for PowerShell ISE

Since Transport Layer Security protocols on PowerShell may be configured with just ssl (SSL 3.0) and tls (TLS 1.0) by default, you may not want to constantly manually configure the [Net.ServicePointManager]::SecurityProtocol every time you launches your PowerShell ISE.

This section will demonstrates on how to configure PowerShell ISE with Transport Layer Security protocols persistently.


Top


TLS 1.1 and TLS 1.2

To apply persistent configuration of TLS 1.1 and TLS 1.2 to your PowerShell ISE, you will have to define [Net.ServicePointManager]::SecurityProtocol with the appropriate [Net.SecurityProtocolType]::Tls11 (TLS 1.1) and [Net.SecurityProtocolType]::Tls12 (TLS 1.2) properties to a Microsoft.PowerShell_Profile.ps1 file.

Note: It is highly recommended to exclude SSL 3.0 and TLS 1.0 usage if your environment is up to date and only uses TLS 1.1 or TLS 1.2 Transport Layer security protocols.

1
2
3
4
5
6
7
8
9
@"
# Configure PowerShell Transport Layer Security Protocols
[Net.ServicePointManager]::SecurityProtocol = `
    [Net.SecurityProtocolType]::Tls11,
    [Net.SecurityProtocolType]::Tls12 ;
"@ | `
Out-File `
    -FilePath "$ENV:USERPROFILE\Documents\WindowsPowerShell\Microsoft.PowerShellISE_Profile.ps1" `
    -Append

Top


SSL 3.0, TLS 1.0, TLS 1.1 and TLS 1.2

If you have to work with legacy Transport Layer Security protocols because your internal environment have not been upgraded to compliant with the new standard yet, you can still configure your PowerShell ISE to include those legacy SSL 3.0 and TLS 1.0 Transport Layer Security protocols.

Note: It is still highly recommended that you upgrade your environment to support TLS 1.2 or TLS 1.1 and stop using SSL 3.0 and TLS 1.0.

1
2
3
4
5
6
7
8
9
10
11
@"
# Configure PowerShell Transport Layer Security Protocols
[Net.ServicePointManager]::SecurityProtocol = `
    [Net.SecurityProtocolType]::Ssl3,
    [Net.SecurityProtocolType]::Tls,
    [Net.SecurityProtocolType]::Tls11,
    [Net.SecurityProtocolType]::Tls12 ;
"@ | `
Out-File `
    -FilePath "$ENV:USERPROFILE\Documents\WindowsPowerShell\Microsoft.PowerShellISE_Profile.ps1" `
    -Append

Top


Conclusion

That’s all, folks. There is nothing wrong with your Invoke-WebRequest, Invoke-RestMethod or PowerShell. It is just that technology has moved on and those default (Ssl3, Tls) might not be default in technologies surrounding us on this world tomorrow.

As for TLS 1.3 protocol, it is still a draft Transport Layer Security protocol and therefore it is not implemented in .Net Framework yet since this blog is posted.

If you happen to like what you just read in the blog post, feel free to share the blog post to others and keep them informed.


Top


References


Top



Top