Force PowerShell to use TLS 1.2
Recently I’ve begun to move the Chocolatey packages I maintain from manual to automatic updating. Going through each package I came across an issue with Yubico Authenticator while retrieving the downloads page using Invoke-WebRequest
This caught me by surprise as I was retrieving other Yubico website pages, such as developers.yubico.com, without issue.
I decided to look at the SSL / TLS protocols for the pages using SSL Labs SSL online test and found the following:
developers.yubico.com
yubico.com
Comparison of Supported TLS Protocols
We are obviously dealing with two different websites here and not pages on a single website. One is yubico.com and the other is developers.yubico.com. Each site has different SSL / TLS protocols that it will accept:
- developers.yubico.com - will accept TLS 1.0 through to TLS 1.2;
- yubico.com - will only accept TLS 1.2;
PowerShell and SSL / TLS
By default PowerShell will use TLS 1.0 when using Invoke-WebRequest
. This is why it cannot establish a secure session with yubico.com as that site doesn’t ’talk’ TLS 1.0 only TLS 1.2. So we have to force PowerShell to use TLS 1.2:
# Force PowerShell to use TLS 1.2
# you should be able to miss the 'System.' and just use 'Net.'
PS> [Net.ServicePointManager]::SecurityProtocol =
[Net.SecurityProtocolType]::Tls12
# Query yubico.com site
PS> Invoke-WebRequest "https://www.yubico.com/support/knowledge-base/categories/articles/yubico-authenticator-download/"
We now get the site data returned as we’d expect.
Which TLS versions does PowerShell support?
The versions of TLS that we can use is already defined for us in the Net.SecurityProtocolType
enum:
# Get the BaseType of Net.SecurityProtocolType
PS> [Net.SecurityProtocolType]
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True SecurityProtocolType System.Enum
# Get the PowerShell supported TLS versions
PS> [enum]::GetNames([Net.SecurityProtocolType])
SystemDefault
Ssl3
Tls
Tls11
Tls12
# Force PowerShell to use TLS 1.1
PS> [System.Net.ServicePointManager]::SecurityProtocol =
[System.Net.SecurityProtocolType]::Tls11
# Force PowerShell to use it's default of TLS 1.0
PS> [System.Net.ServicePointManager]::SecurityProtocol =
[System.Net.SecurityProtocolType]::Tls
So we can force PowerShell to use TLS 1.0 (Tls
), TLS 1.1 (Tls11
) or TLS 1.2 (Tls12
) but not TLS 1.3 as there is no definition for that. Trying to force it results in:
# Force PowerShell ti use TLS 1.3
$> [Net.ServicePointManager]::SecurityProtocol =
[Net.SecurityProtocolType]::Tls13
Exception setting "SecurityProtocol": "Cannot convert null to
type "System.Net.SecurityProtocolType" due to enumeration values
that are not valid. Specify one of the following enumeration
values and try again. The possible enumeration values are
"SystemDefault,Ssl3,Tls,Tls11,Tls12"."
TLS 1.2 is the last version that PowerShell supports.