How to use WCF Message Security with external clients - wcf

Here's my scenario:
I need to host a WCF web service app that will be consumed by multiple customers. Each customer is responsible for their own client app, and they will be building their client apps with different technologies. It's likely that none of their clients will be .Net (probably will be Java or something else).
I need to implement Message Level Security to abide by their policies (Transport security is not sufficient).
Given the above requirements, I am having a hard time understanding how to implement Message Security in WCF that can be used by clients that I do not control. Everything I've read discusses the scenario where I would be building my own client, and that the client would even be in my network's domain.
If I implement Message Security with Certificate, can I install one certificate on my server and have each client be responsible for installing their own certificates on their servers? Would we then be able to use Message Security by simply sharing the Public Keys?

Basically, what you're saying here in your last paragraph is true. You'd give the subscribers of your WCF service the public key (.cer) file that they'd install and register within the LocalMachine/My store of their client machines.
On the host side, you'd install the cert public key in your LocalMachine/TrustedPeople store and the private key (.pfx or .pvk) in the host LocalMachine/Personal store.
You can vary the location of where you install/registry the public and private keys a bit, but then you'd have to configure your WCF service to find those cert elements on your server. The clients would have to do the same.
This does work. I've done it.
You can automate some of this using a .bat file and the makecert.exe and certmgr.exe DOS commands to ensure everything gets installed in the correct places.

Related

SSL Certificate prerequisites to consuming an HTTPS service

I realize the number of question about SSL certificates is legion, but after much searching I couldn't find a precise answer to the following confusion.
For one-way SSL, under what circumstances does the consumer of an HTTPS web service need to import the provider of said web service's certificate/public key? I've consumed a few web services over https before and never had to add the other company's certificate or public key to the key store (or is it trust store?) of any device at my company.
And yet apparently sometimes that is the case, as evidenced by these examples:
certificate mechanism between webservice provider and consumer
Consuming RESTful service over https with certificate using Java
Is it only necessary when the provider of the service's certificate is not issued by a CA known to the consumer?
Also, if the consumer does end up having to import the provider's certificate, AND it's the case that the consumer's consuming app itself consists of a client part and a server part, does the consumer import it into the store of the consumer's web server or into the store of each and every client computer at the consumer's company?
Finally, for two-way SSL, does the consumer send his own client certificate with code that executes on his (possibly many) client computers or on his own web server?
Thanks for any clarification.
Is it only necessary when the provider of the service's certificate is not issued by a CA known to the consumer?
yes. When relying party uses certificates from a globally trusted CA, there are no extra actions required to install foreign certificates.
into the store of each and every client computer at the consumer's company?
if issuer is not globally trusted, it must be installed on every device that consumes service with custom certificate.
does the consumer send his own client certificate with code that executes on his (possibly many) client computers or on his own web server?
it's unclear what do you mean. Can you elaborate?
update:
It depends on how 3rd party server authenticates you. Are they ok to identify your app as whole or they require to distinguish every internal user. In first case, it is enough to have single client certificate within your app and you will have two separate TLS connections:
3rd party server <--TLS--> Your App <--TLS--> End user (many)
End users connect and authenticate only on your application. When necessary, your app establishes a separate TLS connection to 3rd party and work is done. It is quite common practice. End users are not aware of 3rd party server and 3rd party server is not aware about your internal users (and probably should not be).

Protect some methods of WCF service

I have a WCF service that runs on my machine and provides data to everyone.
I need to limit access to some methods only to a certain assembly, not depending on the user that is making the request.
I read about PrincipalPermission and certificates but I'm not sure if this can be useful to me, does anyone know how to make it?
You can use client certificate authentication (whether message or transport - does not matter). Add the client certificate to a trusted people store on the server side, and embed the client certificate keys (e.g PFX) in a resource.
Since not all the methods should be protected, you can create two services that expose different functionality of the same class.

SSL Server-side certificate on client computer?

There is a server with WCF client, which periodically initiates communications over internet with many WCF services installed on our clients computers. WCF services and WCF clients are hosted in Windows Service, current binding is basicHttpBinding.
Communication has to be over https with mutual authentication. Company ordered SSL certificate but it is not clear if this certificate can be installed on clients computers (because WCF service is there) without exposing a private key. Binding can be basicHttpBinding or wcHttpBinding with transport or message security but using certificates.
Is it possible to install service-side certificate on client computers and client-side certificate on our server? Should this architecture be re-worked so WCF service is on our server or it is possible to secure somehow this current solution?
Each computer involved requires it's own certificate. A certificate value for authentication relies on the uniqueness of the private key. The private key never leaves the host machine, and the certificate can be used to authenticate said machine (because is the only one in the world that posses that private key). As soon as you start distributing copies of a private key, security is pretty much compromised.
Normally such deployment rely on PKI infrastructure which can create certificates on-demand and sign them with a trusted key.
What product/protocol the certificates are used for is irrelevant. What kind of WCF HTTP binding you use it maters not.

WCF message security without certificate and windows auth

I have a WCF service and client which is going to be deployed to several companies (hundreds). Some companies will run the software in their network and some will run it over the Internet (WCF server at on office, WCF client at another).
We want to encrypt the communication between the WCF server and client. We don't have any need to authenticate the cient / subscriber using WCF security, because we have our own username/password log-in which the clients will use to log on the server.
We can't rely on Windows auth because some of the users will run it over the Internet, and the WCF server may not be on the same domain as the WCF client.
If we use "real" certificates*, companies running the software would have to purchase certificates from a CA and install it, and then configure our software to use it, but this is too complicated for most of them.
We could auto-create certificates during installation of the WCF server, but then we would have to automatically install it into a certificate store and somehow automatically grant IIS permissions to read the certificate. This is more complicated than we would like.
In short, we want a simple solution where the encryption is just based upon a shared secret, in our case the username / password the user is logging on with. I do understand that this won't give the best available encryption, but we're willing to trade some of the security to make the software easier to deploy.
Is this possible?
*With "real" certificates, I mean certificates purchased from a certificate authority, and not one I've created myself / self-signed.
If you want to encrypt the messages on the transport (which is a really good idea!), there has to be some shared knowledge between the sender (the client) and the server. This can be hardcoded, but that's really not a good idea at all - if that "common shared" knowledge is ever compromised, an attacker could decipher and read all your messages.
Also, since it's definitely not recommended practice, there's no support of any kind in WCF to simplify using a shared secret. You're on your own - you have to roll your own 100% of the way.
The only viable way to have a common shared secret exchanged in a safe way is to use a certificate. No way around this, sorry. The certificate doesn't even have to be used for user authentication or anything - but it establishes a shared secret between the caller and the service and thus allows the caller to encrypt the messages in such a way only the intended recipient can actually decrypt and use them.
So I really don't see any way you can get around having certificates on your servers - doesn't need to be on every client, but on every server where your service runs.
Marc
PS: if you really want to investigate the "hardcoded shared secret" approach, you'll need to think about this:
how do you store a shared secret safely on each and every single one of your clients?
how do you use information from that stored shared secret to encrypt your messages?
Typically, the approach would be two-fold:
exchange some form of a private/public key pair; the server generates a key pair and keeps the private key to itself and shares the public key with the client (e.g. over a WCF message, for instance)
using that private/public key pair, exchange a common shared secret, e.g. an "encryption key" that will symmetrically encrypt your messages (and since it's symmetrical, the server can use the same key to decrypt the messages)
setup infrastructure on your client (e.g. a WCF extension called a behavior) to inspect the message before it goes out and encrypt it with your shared secret
All in all, it's really not trivial - anything simpler than that is not worth being called "security" at all.
If you look at all that work you will have to do - wouldn't it be easier to just use the WCF built-in certificate mechanisms??
Decent security worth its salt is hard - so why not leverage what's available instead of doing all the work yourself, or worse: come up with a half-baked solution that's so easy to crack you could just as easily send everything in cleartext..... don't under estimate the complexity and amount of code needed to handle even the most basic security scenarios - WCF does this all for you - for free and in a reliable and safe manner - use it! You won't regret it!
Well, with WCF you could use Password credential at message level and SSL at transport level, which I think would be enough in your case.
See here.
For message security, your client provides some credentials and server provides some credentials. For this setup and with your scenario could you not use the client username and password with a Custom Username Validator, and a server certificate to provide the server credentials. This Application Scenario provides a fair chucnk of the configuration setup you would need to achieve this, except the aspNet membership sections, which you would have to replace with your custom validation config.
You would still need valid certificates on your servers (no certificates required on the clients), but I can't see any way around this.
Take a look at the following sample:
http://www.codeproject.com/KB/WCF/wcfcertificates.aspx
It uses certificates but without a certificate store - so no setup is necessary.
Hmm.. maybe something simple could be used. Move the encryption from software to hardware. VPN from each client network to your own and then you can do whatever you like for WCF transport. The line is not clear text and the problem is solved.
Of course this is easier said than done, but most network vendors provide a pretty easy VPN config and it maybe easier than trying to develop an installer for SSL certs and configure the client.
I hope it helps!

How can I easily deploy a certificate with a host application?

My use case is very simple : I have a GUI application, and inside this application I host a service however clients of this services must be able to authenticate with UserName safely (The only thing I want is to encrypt messages to be sure that nobody can sniff to retrieve password of clients, I don't care about more security).
So, I want to ship a certificate with my GUI application and that my host (which is inside the GUI application... I know it's a little dirty) use the certificate to encrypt messages.
So my question is : Does my requirements oblige me to install the certificate inside the store on the host machine ?
Am I obliged to generate a new certificate with makecert for every host ?
What is the easiest way to deploy my application ?
(I control the client application so the validation of the certificate is not a problem)
First of all you should not use makecert to generate production certificates.
You could store the certificate in code and not in the machine but keep in mind that the security of the whole encryption is as good as the security of the certificate's private key. If the machine where the application will be run is secure you could use the certificate "incode" but if you cannot guarantee the security of the host machie you should install the certificate in Windows Store. Make sure the user running the application has permissions to read the certificate's private key.
If using WSE or WCF make sure you test the default message or transport encryption methods provided to see if they are good enough for your use.
Here is some references for installing certificate with private key (.pfx file) programmaticly.