How to use tsl version 1.0 in C# server? - c#

Welcome, Im interesting in creating my own local service, witch support TSL v1 only.
I know its weak. But some app does not allow use modern cert above 1.0...
This app has no update to long, and just update it to TSL 1.3/1.2 is impossible.
There two question in complex.
How to create self-signed cert (private and public key) v1.0
How to use this cert in C#, im binding loop back address.
maybe soft like makecert/openssl can help? Which crypt-algorithm i should to use?

This answer is for .NET Core 2.0 and above.
This guide Kestrel web server implementation in ASP.NET Core, it is a guide to create a server.
The certificate and TLS version can be configured in Kestrel server HTTPS defauls:
app.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls;
listenOptions.ServerCertificate = x509Certificate2; // instance of X509Certificate2
});
});
The value SslProtocols.Tls specifies TLS 1.0 security protocol.
How to create a valid, self-signed, X509Certificate2, needed in the code above, is described here. Certificates API was added to .Net Core on 2.0 version.

Related

How to implement TLS 1.2 in ASP.Net Core 2.0

Platform Details: C#, .Net Core 2.0, WS 2016, IIS & Kestrel in reverse proxy
My web app must use HTTPS and TLS 1.2. It was running fine with SSL already, but that is inadequate. I found details online about registry edits needed for TLS 1.2 as default on my web server, and made those changes. After these registry edits, my original code still worked. To force the use of TLS1.2 I added the following to my UseKestrel() in the buildwebhost method.
options =>
{
options.Listen(System.Net.IPAddress.Loopback, 443, listenOptions =>
{
listenOptions.UseHttps(new HttpsConnectionAdapterOptions { SslProtocols = SslProtocols.Tls12 });
}
}))
Now the site is throwing a 502.5. IIS is configured with the original certificate and the site is bound to port 443. I've been told the cert itself is the same between SSL and TLS, so I don't need to get another. When I attempt to debug the code with local host my VS returns an error saying
System.ArgumentException: 'The server certificate parameter is required.'
I have found detail of an "X509Certificate2" object, and some different implementations where the author is using a load method to stream that certificate from a location on the server, but I don't know if that's what's needed here.
The answer is in the comments of the question. The server was provided with an image that didn't include TLS 1.2 by default so the registry edits we did were actually required, but nothing more

TLS Issue using the Demo site

Since today, I am receiving the following error message when sending a package:
Error calling Login: The request was aborted: Could not create SSL/TLS secure channel.
My code
StringBuilder authHeader = new StringBuilder(
$"{{\"Username\":\"{userId}\", \"Password\":\"" +
$"{password}\", \"IntegratorKey\":\"{IntegratorKey}\"");
authHeader.Append(
string.IsNullOrEmpty(senderEmail)
? "}}"
: $",\"SendOnBehalfOf\": \"{senderEmail}\"}}");
Configuration.Default.AddDefaultHeader(
"X-DocuSign-Authentication",
authHeader.ToString());
AuthenticationApi api = new AuthenticationApi();
return api.Login();
Coincidently, today is THE day where TLS1.0 was disables on the demo site of DocuSign. (source)
While I was aware of that, my application uses the .NET 4.7 framework which will uses TLS1.2 by default. Hence, it should not be a problem
As I use the DocuSign NuGet package found here, I looked in the source code and it uses .NET 4.5 (which uses TLS1.0 unless told otherwise)
I understand that I could implement this solution but, shouldn't it work since my application uses .NET 4.7 ?
TLS 1.1 or above is required for all DocuSign APIs and endpoints.
All our libraries now support TLS 1.2 including the the DocuSign eSign C# Nuget package.
See here - https://support.docusign.com/en/articles/End-of-TLS-1-0-and-weak-cipher-support

Ignore SSL self signed certificate errors Restful httpclient

I have done tons of searching and reading on this, there are so many different ways to achieve this. However, things have changed a bit since a lot of the posts. Ultimately, I am using a UWP (10586 minimum target) app. I have wrapped my httpclient code into a .net standard library which my UWP app consumes. However, because of the 10586 SDK version, my .net standard library must be 1.4 or lower.
I need to post json to a web service in a RESTful way. Tjis web service uses SSL but has a self signed certificate. So, I get certificate errors. I simply want to ignore them so I can make my calls. Using 3rd party web service test utility (Postman), I have confirmed the calls will work if SSL errors are simply ignored.
Based on my UWP and .net standard setup, I cannot use the X509 namespace to ignore SSL errors. This is one method but X509 is not available.
So, this looked most promising: https://blog.roushtech.net/2016/12/20/ignoring-ssl-certificate-errors-net-core-httpclient/
It has no compiler errors, but at runtime I get a "platform not supported" exception.
Is there any way to work around all of this given my configurations?
EDIT: The exact snippet I am using that seems to be the supported method in the future but gives platform error on UWP is the same in the link I copied above. For reference, this is what I am doing:
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message,
cert, chain, errors) => { return true; };
using (var client = new HttpClient(httpClientHandler))
{
// Make request here.
}
}
Also, yes my code does work with non ssl (http) calls. It had been working fine for some time until I needed to access a new/different web service which is configured as ssl.
Thanks!!!

Which versions of SSL/TLS does System.Net.WebRequest support?

Now that SSL 3 has been found to be vulnerable to the POODLE attack:
Which versions of SSL/TLS does System.Net.WebRequest use when connecting to any https Uri?
I use WebRequest to connect to several 3rd party API's. One of these has now said they will block any request that uses SSL 3. But WebRequest is part of the .Net core framework (using 4.5) so it is not obvious what version it uses.
This is an important question. The SSL 3 protocol (1996) is irreparably broken by the Poodle attack published 2014. The IETF have published "SSLv3 MUST NOT be used". Web browsers are ditching it. Mozilla Firefox and Google Chrome have already done so.
Two excellent tools for checking protocol support in browsers are SSL Lab's client test and https://www.howsmyssl.com/ . The latter does not require Javascript, so you can try it from .NET's HttpClient:
// set proxy if you need to
// WebRequest.DefaultWebProxy = new WebProxy("http://localhost:3128");
File.WriteAllText("howsmyssl-httpclient.html", new HttpClient().GetStringAsync("https://www.howsmyssl.com").Result);
// alternative using WebClient for older framework versions
// new WebClient().DownloadFile("https://www.howsmyssl.com/", "howsmyssl-webclient.html");
The result is damning:
Your client is using TLS 1.0, which is very old, possibly susceptible to the BEAST attack, and doesn't have the best cipher suites available on it. Additions like AES-GCM, and SHA256 to replace MD5-SHA-1 are unavailable to a TLS 1.0 client as well as many more modern cipher suites.
That's concerning. It's comparable to 2006's Internet Explorer 7.
To list exactly which protocols a HTTP client supports, you can try the version-specific test servers below:
var test_servers = new Dictionary<string, string>();
test_servers["SSL 2"] = "https://www.ssllabs.com:10200";
test_servers["SSL 3"] = "https://www.ssllabs.com:10300";
test_servers["TLS 1.0"] = "https://www.ssllabs.com:10301";
test_servers["TLS 1.1"] = "https://www.ssllabs.com:10302";
test_servers["TLS 1.2"] = "https://www.ssllabs.com:10303";
var supported = new Func<string, bool>(url =>
{
try { return new HttpClient().GetAsync(url).Result.IsSuccessStatusCode; }
catch { return false; }
});
var supported_protocols = test_servers.Where(server => supported(server.Value));
Console.WriteLine(string.Join(", ", supported_protocols.Select(x => x.Key)));
I'm using .NET Framework 4.6.2. I found HttpClient supports only SSL 3 and TLS 1.0. That's concerning. This is comparable to 2006's Internet Explorer 7.
Update: It turns HttpClient does support TLS 1.1 and 1.2, but you have to turn them on manually at System.Net.ServicePointManager.SecurityProtocol. See https://stackoverflow.com/a/26392698/284795
I don't know why it uses bad protocols out-the-box. That seems a poor setup choice, tantamount to a major security bug (I bet plenty of applications don't change the default). How can we report it?
When using System.Net.WebRequest your application will negotiate with the server to determine the highest TLS version that both your application and the server support, and use this. You can see more details on how this works here:
http://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake
If the server doesn't support TLS it will fallback to SSL, therefore it could potentially fallback to SSL3. You can see all of the versions that .NET 4.5 supports here:
http://msdn.microsoft.com/en-us/library/system.security.authentication.sslprotocols(v=vs.110).aspx
In order to prevent your application being vulnerable to POODLE, you can disable SSL3 on the machine that your application is running on by following this explanation:
https://serverfault.com/questions/637207/on-iis-how-do-i-patch-the-ssl-3-0-poodle-vulnerability-cve-2014-3566
I also put an answer there, but the article #Colonel Panic's update refers to suggests forcing TLS 1.2. In the future, when TLS 1.2 is compromised or just superceded, having your code stuck to TLS 1.2 will be considered a deficiency. Negotiation to TLS1.2 is enabled in .Net 4.6 by default. If you have the option to upgrade your source to .Net 4.6, I would highly recommend that change over forcing TLS 1.2.
If you do force TLS 1.2, strongly consider leaving some type of breadcrumb that will remove that force if you do upgrade to the 4.6 or higher framework.

Invoking Java web service from C# client using JKS and/or PFX certificates

I basically need to secure my requests towards this service.
I've been provided a JAR test client and two files, trust.jks and Client.pfx, but I have no clue how to use them: I understand X509Certificate2 class is involved in some way.
The command line to execute the test client is the following:
java -Djavax.net.ssl.trustStore=trust.jks -Djavax.net.ssl.trustStorePassword=******** -Djavax.net.ssl.trustStoreType=JKS -Djavax.net.ssl.keyStore=Client.pfx -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=******** -jar TestClient.jar https://myServiceurl
It works, so I can both see the service, and the service itself should be properly configured.
My C# client (it's targeting .NET 2.0) uses a normal Web Reference to perform requests:
wsReferenceClient service = new wsReferenceClient();
//certificate code here ?
//maybe service.ClientCertificates.Add(<X509Certificate2 object built somehow>); ?
service.MyRequest(myParameters);
Server settings should be setup properly.
I fumbled around with the X509Certificate2 methods but I can't come out with something that makes sense, so the answer to the 'what have you tried?' question at the moment is 'I don't really know what to try in the first place'.
Any help would be really appreciated.
Turns out I don't need to do anything with the JKS file.
wsReferenceClient service = new wsReferenceClient();
X509Certificate2 cert = new X509Certificate2();
cert.Import("Client.pfx", "<the password>", DefaultKeySet);
service.ClientCertificates.Add(cert);
service.MyRequest(myParameters);
This allows my HTTPS requests to go through successfully.

Categories