Using certificate only on server side - c#

I'm working on some WCF application. I already have client-side and server-side. Both communicates using WCF netTcpBinding or netNamedPipe. I want also a certificate only on server side, similar as it is with HTTPS. I've found very helpful guide here click.
So according to this article, I'm interested in option 1 which is
Option one provides (C + I) no authentication will happen for the client, In this case the TCP SSL (not the HTTPS SSL) will be used to provide the Confidentiality and Integrity, and the service will be configured like this below.
For now everything is clear for me, unfortunately later we can read:
also you need to install the root certificate authority certificate for the service certificate on the client machine (typically in the Local Machine/Trusted Root Certification Authorities), and the service needs to have the below behaviour to specify the certificate for the service.
So here comes my question, is there any way to avoid changes on client machine? As mentioned earlier, I'm looking for a solution similar to WEB where the user is not obligated to install any kind of certificate on his machine.
Maybe I'm missing something, but maybe this rule applies only when I'm using a self-trusted/developer certificate? What if I will get certificate from a trusted company like Verisign?

Install the certificate on the client-side simply to guarantee that the service on the server-side is trusted and that communication I secure. Just like visiting a website, we usually have a built-in certificate for the site before we browse the website, so the browser prompts the website is trusted. Unlike self-signed certificate, website certificates are issued by trusted third-party organizations to a specific host (web server), so all we need to do on the client-side is to install authoritative trusted third-party certificate before accessing the website. but we directly install the server-certificate on the client-side when we configure a self-signed certificate in the Local CA.
In fact, Browsers/OS already have some authoritative third-party certificate built-in. such as GlobalSign, VeriSign, so we just need to buy a certificate from them and configure them on the server-side, in which case, the client always trusts the server.
In addition to installing the server-side certificate, we may also need to configure the server-side identity on the client-side, which is usually the public key of the certificate, or the hostname. These configurations are generated automatically if we generate the client proxy and invoke the service by adding a service reference.
Feel free to let me know if there is anything I can help with.

You don‘t need install somethings when you use an certificate issued by an trusted CA like GoDaddy and so on.

Related

How could I ship SSL certificate update to a running app?

My company has got a software that is used on-premise and installed as a Windows service. We are adding now a WebAPI to it using .NET core 2.1. This API should be secured with SSL and if we buy a certificate it will last at most two years. Is there any way of automatically updating the certificate used for HTTPS? Some customers buy the software and don't upgrade as often as we would like. How could we ship a new certificate for them?
Update 07/03:
Our on-premise solution has been working at the backend as a service for 6 years (with two major updates per year). Now we are integrating a webapi in this service. No IIS here, just a self hosted webapi. Our service could use our own SSL certificate but then we will need to replace it somehow when it expires.
How could I ship SSL certificate update to a running app?
You don't need to distribute the server certificate to client devices if it is signed by a CA they trust.
Ideally the client systems should trust a Certificate Authority (CA) that has a very long validity period (e.g. 20 years). That CA then issues short-lived certs (e.g. 6-12 mo) to the webservers. The clients will trust these certificates because they are signed by the CA they trust.
This is how the public web works today. The CA's are companies with big insurance policies, like Verisign, and the OS or browser vendors determine whoch CA's make the cut and get included into the certificate bundles which they manage by their own mechanisms (e.g. automatic updates).
So an option is to simply buy an HTTPS certificate from a public CA.
You can also be your own CA, but then you need to manage protecting the highly-sensitive root CA keys, and the distribution of your CA cert to all of the client devices.

Require SSL Client Certificate only for specific routes or controllers

I have an ASP.NET MVC Core project using Kestrel as the server. It is both serving up user content (asp.net mvc) and hosts web API controllers that agents (software) communicate with. I have enabled HTTPS and client certificate support. The issue is that I want to require client certificates for agents (software) that call Web APIs but I do not want to require/prompt for client certificates for regular browser based users.
I have enabled HTTPS/client certificate support the following way:
var host = new WebHostBuilder()
.UseKestrel(options =>
{
HttpsConnectionFilterOptions httpsoptions = new HttpsConnectionFilterOptions();
httpsoptions.ServerCertificate = CertUtil.GetServerCert();
httpsoptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
httpsoptions.CheckCertificateRevocation = false;
options.UseHttps(httpsoptions);
})
.UseUrls("http://0.0.0.0:5000", "https://0.0.0.0:5001")
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
host.Run();
I have a separate middleware handler setup in Startup.cs to handle custom verification of client certificates. This code does successfully execute and everything works fine in that sense.
The problem is this happens globally and I am only looking to apply client certificates to specific controllers and/or routes; or really I would take any granularity at this point.
Essentially trying to create the same sort of behavior you can get in IIS by creating two virtual directories and then setting SSL Settings to Accept on one and Ignore on the other. The one with Accept will prompt the browser for a cert and the one with Ignore will not.
I tried setting HttpsConnectionFilterOptions to only specify ServerCertificate in hopes that not setting any client certificate related options would allow the server to receive client certificates if they are sent but otherwise not prompt browsers for them. This did not seem to work as my middleware client certificate handler never sees a client cert when calling this function (it does when ClientCertificateMode is set to AllowCertificate.
context.Connection.GetClientCertificateAsync();
I guess in short does Kestrel hosting even allow for more granular client certificate mapping/handling or is it only possible using IIS? IIS is not an option for this project and I would rather prefer not having to create a separate project/process just for the client cert api aspects. Appreciate any help!
I've been trying to do the same thing, with exactly the same requirements as you.
I've come to the conclusion that it's not possible. My workaround is to use 2 WebHostBuilder objects - one for locations that don't need client certs, and one for those that do. This does have the downside that each IWebHost must listen on a different port, but from the scenario you describe I guess that's not a big issue.
I do this within the same process, so this solution fits that requirement.
I had the same issue with context.Connection.GetClientCertificateAsync(); it was always returning null. Then I noticed that I was running Kestrel thru IIS Express all the time.
So in Visual Studio from the Debuger toolbar I changed from IIS Express to my project. Kestrel was started as console application and I was able to get the client certificate.
I think that IIS Express does not support client certificates so the certificate was always ignored.
For the other part of the question; I think Kestrel dos not support this granularity that you are looking out of the box when using the HttpsConnectionFilterOptions. From the Kestrel Connection Filter Options source code the connection will be dropped if the client certificate is null. Maybe you can modify the source code for the HttpsConnectionFilterOptions and create your own filter from it. Then you can use the ClientCertificateValidation property to specify custom certificate validation method that will allow the connection when no client certificate is send.
Hope this helps.
I have figured out how to have Client Certificate only on some routes but when run in Azure Web App, the client cert is not being passed to the code. It is the same problem when running under IIS Express.
In this example, One controller needs no cert, the other two requires different certs.
https://github.com/xavierjohn/ClientCertificateMiddleware
The certificate does get passed through if it is not run under IIS Express.
There is no need to use isolated (new one) IWebHost to control access to dedicated MVC controllers.
Just use Athorization Filter for this purpose.

Unable to login the application when using IIS Express Development Certificate in SSL

I have implemented SSL connection in my application. For this I have added IIS Express Development Certificate while hosting the site in IIS.
I could use other pages with SSL. ie., https://localhost/general
I am unable to login the application using SSL. My url changing like https://localhost/accounts/login and becomes empty page.
I am getting the below error in Firefox browser.
This site makes use of a SHA-1 Certificate; it's recommended you use certificates with signature algorithms that use hash functions stronger than SHA-1.
I have tried by using Self-signed certificate also.
Is this problem arise because of IIS Express Development Certificate ??
Either you use full IIS or IIS Express, the default self-signed certificates generated are SHA-1 only, and now become obsolete.
To generate SHA-2 certificates, you can use Jexus Manager,
https://blog.lextudio.com/2016/03/jexus-manager-enhanced-self-signed-certificate-generation/

Self hosted C# SSL web server without requiring admin rights

We have self-hosted C# WCF service providing rest API over HTTPS.
Problem:Configuring the certificates for SSL requires admin rights. I assume it is to do with WCF depends on http.sys for http/https handling. The service is meant to be deployed on customer environments. So it would be nice if it can run without requiring admin rights.
Looks like WCF depends on http.sys,
Can I self-host an HTTPS service in WCF without the certificate store and without using netsh http add sslcert?
Like to know if any other embedded web server solution exist that support SSL and not requiring admin rights on the machine?
Checked so far,
http://nancyfx.org/
https://github.com/pvginkel/NHttp
Both doesn't seem to support SSL.
Most windows hosted web stacks rely on the HTTP Server API which is the API around the kernel HTTP stack (a.k.a HTTP.sys). The .Net HttpListener class does so as well (same as WCF, the OWIN self hosted asp.Net and so on which rely on it).
Just making sure, you do know you can authorize the identity you application runs under to bind to an HTTPS URL even if it's not running as an admin account, right? If you could gain admin right just for the installation phase that could solve you problem? (assuming you checked that already)
You can read more on a blog post i wrote about that here
To go into the effort of building an http stack on top of raw sockets would be a great effort and with little gain and so around .Net i doublt you would find anything like that.
Unless, it wished to be cross platform.
Any java based web server would probably do just that, using the JVM's http stack and relying on a java keystore to provide the required certificates for the SSL. (To keep it portable across different OS's)
If you wanna go java i am sure you can find many such web servers.
If you care to try and bind to a web server using CGI have a look at mongoose (Never used it to be honest).
Another option which comes to mind is to use an ssl proxy like Stunnel to stand in front of the web server. It would do the SSL part using non-windows certificate store.

Communication between web applications, 1 SSL certificate, other has none

This the situation: I have one webservice without SSL, which provides two pages for the other web application. When the user submits these pages, an XML file with private information is sent to the webservice.
How can I provide the necessary privacy protection on the XML file? Is the one certificate good enough to give the appropriate security?
I'm not sure about this one, and am in the preparation phase of a project... So need to know the involved work on this part...
As an alternative to SSL you could encrypt the file yourself using any of the algorithms available in using System.Security.Cryptography but then you have to work out a mechanism to exchange your key(s).
However by far the easiest way will be to have both web services using SSL endpoints. That will take care of all your confidentiality, integrity and identity considerations in one fell swoop.
Certificates are tied to the hostname of the server (or, with wildcard certificates, all the hosts in a domain). So if the two services are on the same host, then both can use the same certificate.
If they are not on the same host there will be no transport security on the non-SSL service unless this is added separately. WCF has support for message (or part of message) encryption.
The simplest solution is certainly to use TLS, ex-SSL (widely supported in every programming language).
There is no need to buy a certificate (and it brings no extra security, it is mostly there to make PHBs feel better): either create self-signed certificates or set up your own CA.

Categories