I have a client/server WCF application that needs some sort of user authentication against a database. The application (both client and server together) is being developed to be sold to dozens of customers, for use on their intranets. We're not too worried about encrypting most of the data moving across the wire, except of course during authentication.
Thinking about WCF security, I keep coming back to the idea that we should be making use of x509 certificates. However, our customers will definitely not want to know about any of the details of having to apply for, purchase and install these certificates.
I'd like to know first of all what the preferred method is of implementing username/password authentication in this scenario. If it will require using certificates, must the customer apply for their own certs from a trusted CA, or can we as the software provider generate certificates for the customer to use?
Really I'm looking for a best practice, with the least friction to our customers.
Thanks!
Edit: I'm using NetTcpBinding, and my server is running as a Windows Service.
So username/passwords does not require client certificates as I'm sure you're aware, it simply requires an HTTPS certificate on the server hosting the WCF service - once you have that you can happily use the standard username/password auth bits (WCF will not allow message based authentication without HTTPS).
If you wanted to head down the client certificate root you get the advantage of non-repudiation - you can be sure that the machine sending is who it says it is (unless someone has stolen the certificate, which is less likely than a username and password combination going walk about). You as the software provider could act as your own certificate authority and generate your own client certs (there are a few ways to do this depending on your infrastructure) but then you need to configure the clients to trust your root CA.
If the server and client are running in a domain environment you could use transport security with Windows authentication (you're using tcp binding, so interoperability is out the window anyway!) The added bonus to this is the authentication is transparent and you don't need any certificates anywhere. If you want verfication of the server identity then message security with Windows authentication will do the trick.
I've got project in production which is similar to your scenario. I have a Windows Service hosting endpoints via netTCPBinding and I used x509 certs... although in my case, the intent was to encrypt both the transport and message layers, as I was crossing over untrusted security boundaries. I was less concerned with providing authentication/authorization other than requiring the certificate be present.
Similar to your intranet scenarios (I'm assuming), I had authority over the server and client machines at installation time... or at least could dictate some of the terms of installation.
Rather than purchase the x509 certs and burden the client with that expense, I opted to roll our own. We set up one of our Win2003 servers to be a CA, issuing our own Certification Authority cert. We then generated an x509 cert for the server, as well as individual x509 certs for the clients.
The client and server certs were installed on both clients and server (as appropriate) into the personal user store at the computer level. We also installed our CA cert directly into the Trusted Root Certification Authorities section, thus making our client and server certs trusted.
Because I was less concerned with authentication/authorization, I don't know what to recommend as a best practice for dealing with binding certs to individual users and going more granular than machine-level (my solution was windows service to windows service communication -- completely unattended). I would think you'd need a cert for each user, installing it into their personal user store in the certificates MMC. The runtime implementation will be guided by how you configure WCF to do the cert lookup, so it should be fairly easy.
Throughout the process, I relied heavily on what I'd learned from this great CodeProject article: Securing WCF Services with Certificates. It walks you through generating/installing the certs. The sample WCF applicatoin is IIS-hosted, but I was able to pretty easily translate the config sections from web.config to app.config.
In my case, I exposed the Web interface for requesting certificates in Win2003 to the web itself, so the client could request certificates directly in the future. We have approval control, so it works well. I haven't had a need to generate new certs yet, so I can't say how much friction that would entail.
If your going to be crossing firewall boundaries then certificates are going to be your best solution. I don't know much about the specifics about applications for certificates or your application. Unfortunately, as far as i know, i think you will have to help them apply for certificates or they will have to do it their self unless they want to undertake in the process of installing their own certificate server. If the app will be internal then windows authentication will work and is VERY easy but if you think your going to have clients that user your application across firewall boundaries then you might as well invest the time in using certificates because certificates will work everywhere. Now there is something called federated security where you delegate the permission of authentication to another entity. I think this is used if say you have to domains and you want to delegate permission say of someone on another domain that is not on your domain to their domain but its pretty complex and my understanding of its very limited but by the sound of your requirements certificates is the way to go.
Security is not supposed to be easy :)
Related
I generated selfsigned certifiacte to use it to authenticate my web appliaction. Clients instead of web browser use client application to comunicate with web server. Client application uses httpclient. The internet is full of examples of how to trust all the ssl certificates in httpclient. I don't want to trust all certificate, I want trust only one, my selfsigned certificate (of course every CA trusted certificate also). I know that I can add my certificate to trusted keystore using keytool, but I don't want to interface in JSSE keystore. I want to say httpclient to trust one specific selfsigned certificate.
First question:
Is it possible?
Second question:
Described solution is ok in development environment. I'm think that is bad practice, but I wonder that is it acceptable in production environment?
Is it possible?
Of course, it is. You just might need to do more work managing your trust material and initializing the SSL context for your application. You can choose to trust one and only certificate, or you can choose to use trust material shipped with JRE and then selectively add trust material specific to your application.
You could use SSLContextBuilder from Apache HttpClient 4.3 to simplify the process of trust and key material management and initialization
is it acceptable in production environment?
This very much depends on the security context and requirements of your application. Trusting only one specific certificate without trusting any of standard CAs might make your application marginally less susceptible to man-in-the-middle exploits but will require re-configuration and possibly redeployment every time the certificate in question expires or gets revoked. It will also become your responsibility to ensure that the private key will not fall into the wrong hands. It is a combination of pros and cons.
I was reading an article about authenticating User with certificate to WCF service. Please correct me if I'm wrong. As per my understanding each user need a certificate to authenticate. How feasible is this in real world where, there are multiple clients? Is it good option to adopt?
Yes each user should have his own certificate. Certificate is used for encryption and signing (asymmetric security) and it can be used also for authentication. Authentication can be also provided by another supporting token but that is not supported by default WCF bindings (you must create your own).
To support such scenario you usually need your own certificate authority (CA) which will issue certificates to clients. It can be either use in corporate network where computers usually trusts corporate CA or it can be used over interned but CA's certificate must be issued by well known and trusted certificate authority (like VeriSign).
It is of course feasible in some scenarios. For example banks using client certificates plus some supporting token for connection to internet banking (that is usually web application scenario and not services but it is good B2C example). It is also sometimes used for communication among business partners (E2E / B2B).
I want to create WCF services using aspnet membership to authorize the user. However, if I just need the certificate for encryption purposes only, does it matter if it is a self signed certificate or do you need to buy a certificate from a vendor?
A self-signed certificate regardless of whether you authenticate the user carries the same risks. Best practice is to use a real cert in a production environment. With some very cheap prices these days, it's not much of a financial burden to take on any more either (unless you're a stickler for Verisign).
It's been discussed and noted that self-signed certs in a production WCF environment also come with heavy performance issues:
Terrible Performance with WCF and certificates (mutual authentication)
http://weblogs.asp.net/cibrax/archive/2006/08/08/Creating-X509-Certificates-for-WSE-or-WCF.aspx
http://www.google.com/search?q=wcf+self+signed+performance
You could use self-signed certificates, but the problem there is that you have to install the certificate on each and every machine that will use the certificate for encryption.
If you have a large number of machines that the clients will run on, this can easily become prohibitive from a maintenance and configuration point of view and it would easily justify the purchase of a certificate from an authority.
I have a distributed application consisting of many components that communicate over TCP (for examle JMS) and HTTP. All components run on internal hardware, with internal IP addresses, and are not accessible to the public.
I want to make the communication secure using SSL. Does it make sense to purchase signed certificates from a well-known certificate authority? Or should I just use self-signed certs?
My understanding of the advantage of trusted certs is that the authority is an entity that can be trusted by the general public - but that is only an issue when the general public needs to be sure that the entity at a particular domain is who they say they are.
Therefore, in my case, where the same organization is responsible for the components at both ends of the communication, and everything in between, a publicly trusted authority would be pointless. In other words, if I generate and sign a certificate for my own server, I know that it's trustworthy. And no one from outside the organization will ever be asked to trust this certificate. That is my reasoning - am I correct, or is there some potential advantage to using certs from a known authority?
There is no need for you to use an external public CA for a closed community project. In many larger organisations they operate an internal PKI to issue certs for internal projects like this. An advantage of using a PKI is that you can setup a trust relationship between the various components based on a single securely distributed root certificate / trust anchor.
However, if the project allowed internal users to connect securely to an internal service via their web browser you may want to consider using a public CA issued cert. The alternative is to make sure that every browser that may need to connect to your service trusted your root cert; this is to prevent browser warning messages.
I'd say it's reasonably safe, unless you think a ninja infiltrator is going to swap your server on you.
The 3rd party is there to make it harder to just 'up & generate' a new cert. Someone could re-create a self-signed cert on a new machine with the same details, it wouldn't be the same cert, you'd have to add an exception for it too, but your users probably wouldn't know the difference.
As long as your system is running inside your group and there are no plans to expand it (and plans do change, so keep that in mind), it is just fine to setup your own simple PKI infrastructure.
If you do end up expanding beyond your organization, all you need to do is distribute your root certificate to the parties you will be communicating. This gives actually a fine grained control to your partners how much trust they want to put in you vs the public CA infrastructure.
I have a WCF Server Deployed through IIS. I want to Create a Certificate for it. I could do this by making the server a certificate server.
But then when the client connects to that server I want the client to automatically trust the certificate without having to register that the server as a "trusted authority".
Is this possible?
All this seems a lot of work to put username password protection on a WCF Service!
The short answer is no the client will need to add the server cert root as a trusted authority.
The slightly longer answer is that there is a workaround for needing to implement transport security in WCF when using message based authentication - this workaround is usually used when you want to rely upon another security mechanism that the WCF server is not aware of, like an ISA server providing SSL.
Have a look at Yaron Naveh's post. The essential idea is that you create a transport binding that pretends that it is secure.
With all that, you still need security (you don't want to send your creds in the clear) and so will still need a trust chain for your cert. So, it may not actually help you, but hopefully it gives you some options to consider.
Edit
Sorry if my answer was misleading. The server certificate root cert must by in the client trusted store. My additional detail was giving another option for providing the security (you can use an ISA server with a trusted cert to give your SSL connection)
In a similar situation to yours (needing secure communication when pushing client applicaitons to non technical customers) I have programatically installed the needed root certs.
Here is an SO post that details how to do that: How can I install a certificate into the local machine store programmatically using c#?
You can if you add this to your code but be aware of what you are doing!
System.Net.ServicePointManager.ServerCertificateValidationCallback += ( se, cert, chain, sslerror ) => { return true; };
Well if there would be such a way, it would be a security hole.
If a certificate is not linked to a trusted authority it is easily forged. So your choice is either to link it one way or another (directly or through a parent certificate you control), or configure your client so that it does not require the certificate i.e. using http rather than https.
Just keep in mind that it leaves your clients open to a variety of attacks
Edit
One of the possible attack scenarios is a man in the middle attack - a program inserts itself between your service and the client and channels the information though itself. This way the intruder has complete control over the information flow.
It can make copies of passwords or it can "adjust" the results in both directions any way it wants. The only thing which prevents this from happening is the certificates. But if they are not rooted, they can be forged.