Force HttpWebRequest and ClientWebSocket to use TLS 1.2 - c#

I´m trying to connect to a websocket with the ClientWebSocket class. I´m using Unity 2017.4.10. Unfortunately C#/Mono is always using TLS 1.0 which for some reason fails. When i examine the connection with Wireshark i get a encrypted alert packet and the connection closes.
I already tried to force TLS 1.2 by setting:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
but still the WebSocket tries to connect with TLS 1.0.
When connecting to wss://echo.websocket.org it works, as websocket.org only supports TLS 1.2. Unfortunately my provider still supports TLS 1.0 1.1 and 1.2.
No matter what i try TLS 1.0 is always used by HttpWebRequest and ClientWebSocket classes.
I know TLS 1.0 is used because Wireshark and Fiddler says so.

Looks like this is a unity bug and fixed in 2018.2
Issue

for Websocket try :
WebSocketClient.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12;

Related

Is it possible to modify TLS handshake in C# HttpClient on .NET Core

Apparently, CloudFlare now has some kind of a whitelist for the possible TLS handshake parameters for every known browser.
Thus, when I'm sending HTTPS requests using HttpClient, CloudFlare considers it a bot and at the very minimum presents a captcha.
The captcha itself is not a problem, I'm using a browser to ask the user to pass it. However, some websites apparently block some requests even after passing the captcha just because the TLS handshake was not whitelisted by CloudFlare.
So I've digged into the .NET Core source to see if I can modify the way TLS handshake packet is built. Unfortunately, it seems that .NET Core itself doesn't build it itself but rather delegates it to the underlying library (OpenSSL on Linux / standard Windows)...
Is the only solution to write my own SSL library?... Sounds like a task for many months.

c# webclient download image fail

We upgraded from windows server 2012 to windows server 2019.
I'm using webclient to download images during a user session.
Use to work perfectly and works locally when I run it.
When I move the source code to windows server 2019 it fails with the standard The underlying connection was closed:
Using .Net 4.6 Using Security Protocol Tls12.
I'm extremely baffled by what is causing the issue
ServicePointManager.Expect100Continue = false;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
using (var web_client = new WebClient())
{
web_client.DownloadFile(file_url, download_file_path_with_name);
}
Does anyone have some other suggestions. I tried with Exter100Continue = true with same results.
There are some big changes in the versions and cipher suites from 2012 to 2019.
First:
I would recommend that you just allow the OS to decide which Security Protocol to use (it will negotiate TLS version and cipher suite with the server that hosts your image). Here is a good article about TLS versioning and .NET versions and OS versions
Second:
I would run something like Fiddler locally on your server to see where the web request is failing (I'm guessing the TLS handshake fails). Fiddler will provide alot more detail about your web requests at the packet level.

Packets not being captured when negotiating TLS versions with .NET SslStream

My set up is:
I have a server listener app that only accepts TLS 1.0 connections.
I have a client app that uses SslStream.AuthenticateAsClient to configure a secure connection
I am using WireShark to monitor traffic between client and server
On the client machine I use the SecurityProviders\SCHANNEL\Protocols registry keys to manipulate which version of TLS I want to use. If I force the client to use TLS 1.2 I get the expected error of "The client and server cannot communicate, because they do not possess a common algorithm". However, the only packets that get captured in WireShark are the TCP 3-way handshake.
Conversely, if I explicitly specify Tls1.2 in the call to SslStream.AuthenticateAsClient I see the Client Hello and Server Hello TLS messages in WireShark. And of course, I see the same expected error message as above.
My question is, when I'm only using the Registry to manipulate TLS versions how come I do not see any TLS packets being sent through WireShark? How does Windows/.NET know that the remote server does not support TLS 1.2?
Thanks

SSL Handshake fails from asp.net application - works in browser

I am trying to do a simple get request using the System.Net.Http.HttpClient (using GetStringAsync). The request fails when done from my webapi asp.net application, but it works correctly from the browser and postman.
The request fails with Authentication failed because the remote party has closed the transport stream.
Note: It works correctly when doing get request to other servers using TLS.
I used the following to confirm that the issue was with ssl. Using these two lines makes the request work, but obviously disabling certificate validation is not a real solution.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
I tested the server using https://www.ssllabs.com and it seems that
everything is working correctly on there. It supports TLS 1.1 and 1.2.
To find out what is going on I was looking at the packages in wireshark, but since I don't know much about ssl, I am not learning much. Looking at the packages from the browser request I can see that it is using the TLS 1.2 protocol and that the handshake looks correct.
The following picture shows the client initiating two separate ssl "ClientHello's". For some reason the server doesn't respond with a SSL handshake response.
Hope someone can help me figure out what is going on.
I tested the server using https://www.ssllabs.com and it seems that everything is working correctly on there. It supports TLS 1.1 and 1.2.
Your client is doing a TLS 1.0 handshake only. If the server supports only TLS 1.1 and TLS 1.2 but not TLS 1.0 the connection will fail. Since modern browsers all support TLS 1.2 browsers will work.

WCF service (self-hosted) over HTTPS - Get negotiated SSL/TLS protocol version

Due to security reasons, we wanted to disable TLS 1.0 support in our server on OS level (in followign SChannel registry):
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols
But because the SQL Server service won't start with TLS 1.0 disabled, we had to leave the TLS 1.0 enabled on OS level.
What we are trying to do now is to force the usage of TLS 1.2 on application level rather than on OS level.
Our application is Client-Server, running on .NET 4.5.
On the Client, before calling the WCF service, we set:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
That ensures that the Client will send ClientHello message with TLS1.2 protocol.
But on the Server, which is self-hosted WCF service, we do not see how to force the TLS1.2 usage. The SSL/TSL negotiation on the Server side is based on the SChannel registry and thus setting the ServicePointManager.SecurityProtocol does not make any effect.
We would like to inspect the incoming WCF call in our Server code and check what TLS protocol used for the call, and close the connection if it is anything less than TLS1.2.
Is there any way how to get the incoming WCF call SSL/TLS protocol version? Something like HttpContext.WebSocketNegotiatedProtocol?
Have you tried using a custom binding with sslStreamSecurity?
<sslStreamSecurity requireClientCertificate="false" sslProtocols="Tls12" />

Categories

Resources