HADotNet
HADotNet copied to clipboard
TLS 1.3 - Authentication failed because the remote party sent a TLS alert: 'ProtocolVersion'.
Environment
- Home Assistant Version: 2023.1.6
- HADotNet Library Version: compiled from the source (06cc98c)
- Visual Studio Version: 17.4.4
- API call or endpoint that is failing: authentication
Describe the Problem
My HA instance forces to use TLS 1.3 and I'm trying to use HASS.Agent which uses this library but during initial connection I got an error: The SSL connection could not be established, see inner exception.
Code Sample
ClientFactory.Initialize("https://my-home-assistant-url/", "AbCdEf0123456789...");
var configClient = ClientFactory.GetClient<ConfigClient>();
var config = await configClient.GetConfiguration(); //error
Exception logs:
System.Net.Http.HttpRequestException
HResult=0x80131501
Message=The SSL connection could not be established, see inner exception.
Source=System.Net.Http
Stack tracek:
w System.Net.Http.ConnectHelper.<EstablishSslConnectionAsync>d__2.MoveNext()
w System.Threading.Tasks.ValueTask`1.get_Result()
w System.Net.Http.HttpConnectionPool.<ConnectAsync>d__98.MoveNext()
w System.Threading.Tasks.ValueTask`1.get_Result()
w System.Net.Http.HttpConnectionPool.<CreateHttp11ConnectionAsync>d__100.MoveNext()
w System.Threading.Tasks.ValueTask`1.get_Result()
w System.Net.Http.HttpConnectionPool.<AddHttp11ConnectionAsync>d__74.MoveNext()
w System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.<WaitWithCancellationAsync>d__1.MoveNext()
w System.Threading.Tasks.ValueTask`1.get_Result()
w System.Net.Http.HttpConnectionPool.HttpConnectionWaiter`1.<WaitForConnectionAsync>d__5.MoveNext()
w System.Threading.Tasks.ValueTask`1.get_Result()
w System.Net.Http.HttpConnectionPool.<SendWithVersionDetectionAndRetryAsync>d__84.MoveNext()
w System.Threading.Tasks.ValueTask`1.get_Result()
w System.Net.Http.RedirectHandler.<SendAsync>d__4.MoveNext()
w System.Net.Http.HttpClient.<<SendAsync>g__Core|83_0>d.MoveNext()
w HADotNet.Core.BaseClient.<Get>d__6`1.MoveNext() w C:\Users\user\Desktop\HADotNet-master\HADotNet.Core\BaseClient.cs:wiersz 38
w HADotNet.Core.Clients.ConfigClient.<GetConfiguration>d__1.MoveNext() w C:\Users\user\Desktop\HADotNet-master\HADotNet.Core\Clients\ConfigClient.cs:wiersz 22
w Program.<<Main>$>d__0.MoveNext() w C:\Users\user\Desktop\HADotNet-master\ConsoleApp1\Program.cs:wiersz 10
Inner Exception 1:
AuthenticationException: Authentication failed because the remote party sent a TLS alert: 'ProtocolVersion'.
Inner Exception 2:
Win32Exception: The message received was unexpected or badly formatted.
I'm sorry, this project does not currently support TLS 1.3. Support could be added, but I do not have a timeframe on when that would be or how much effort it would take.
.NET 6 (which HASS.Agent runs on), as well as .NET Standard 2.0 (which this library is built on) should both support TLS 1.3 out of the box, as far as I know.
I was having the same issue as @VivantSenior, as my Traefik reverse proxy also forces TLS 1.3 - but the authentication worked just fine on my Windows 11 laptop, while it failed with the above error on my desktop PC, running Windows 10.
That sent me down a rabbit hole...and it turns out that Windows 10 apparently "doesn't support" TLS 1.3, according to Microsoft - even the latest version, 22H2.
That was mind boggling to me, but anyway...it seems that there is a registry workaround to enable TLS 1.3 on Windows 10 - or at least, it worked on my PC, which is running 22H2. This is purely a guess, but maybe the inner dependencies needed for the TLS 1.3 client are present in the later versions of Windows 10, since 21H2 was the first build of Windows 11? 🤷♂️
Anyway, this link helped me out a lot - basically, I just created a registry key called TLS 1.3\Client
under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols
, and then added two DWORD values:
-
DisabledByDefault
: Value of0
-
Enabled
: Value of1
After that, reboot the system, and it should work fine. :)
@qJake You might be able to set TLS 1.3 as the default security protocol in your ClientFactory
class, but it's been a while since I've done .NET professionally, so I don't know if you'd still need the registry key on a Windows 10 system. I vaguely recall having to do something like this in my last .NET job, but it was years ago, heh.
Here's a quick snippet (two methods of setting it) I whipped up - I don't have time to add it myself, test it, and create a PR, but this should help you. ;)
// usings
using System.Net;
using System.Net.Http;
using System.Security.Authentication;
// EXAMPLE 1 - Set SecurityProtocol globally
System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
// EXAMPLE 2 - Add an HttpClientHandler to your HttpClient to set non-globally
var handler = new HttpClientHandler()
{
SslProtocols = SslProtocols.Tls13 | SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls
};
var client = new HttpClient(handler);