How do I setup Client and Server Certificates for WCF Transport Security? - certificate

My scenario: I have a public facing web app hosted on Amazon EC2 servers. I have a self-hosted database server behind a firewall. I have self-hosted Web Service servers with a web service for data access. I want to allow only applications I approve (my own living in the cloud) to access the services and I don't want any data passed in clear-text.
From what I can tell reading all the disjointed and maddeningly obfuscated MSDN articles, Stackoverflow threads, Code Project articles, and other blogs. The type of security I need is:
Transport Security mode with Certificate clientCredentialType, using wsHttpBinding. First question, am I right in assuming that? Will that give me enough security? This isn't B2B or anything like that. It is, however, cross domain and I just want to ensure I can trust the caller. My service is running in an AppPool owned by a specific user so I can access the DB with integrated security. I need to make sure only callers to my service that I approve get in. I don't need to encrypt the message anymore than SSL already does I don't believe.
All the scenarios possible make it very very difficult to know if this is what I want. But assuming it is the next question is how do I set up the Certs? I currently have a Certificate on the server, and I can only access with Https. (security mode="Transport", clientCredentialType="None"). But for the life of me I can't figure out what I need to do to change clientCredentialType to Certificate and get it to work.
What do I give the client from the server and where does it go?
What do I give the server from the client and where does it go?
If I have several clients (a web farm) do I have to have a different client cert for all of them, or can they share one cert that my server accepts?
All development articles I read say that Cert setup is an Admin tool and beyond the scope of the article. Well, the WCF stuff is straightforward, it's exactly the friggin cert stuff I need help with, and there are no useful articles that I've found yet. Those that come close show how to do it with makecert.exe and say in production it will be different, but then don't say how to do it in production.
I'm sure my frustration level is showing, sorry about that. But it really makes no sense that there isn't a clear description on how to do what seems like a pretty common security scenario in WCF.
Any and all help appreciated,
Ken

Short Answer
The type of security I need is: Transport Security mode with
Certificate clientCredentialType, using wsHttpBinding. First question,
am I right in assuming that?
Yes. Message security would also work assuming you do not use WCF streaming features, but with transport security you can benefit hardware acceleration.
how do I set up the Certs?
Please see the detailed answer below.
What do I give the client from the server and where does it go?
If I have several clients (a web farm) do I have to have a different
client cert for all of them, or can they share one cert that my server
accepts?
You need 3 certificates :
a client certificate (the same for all clients).
a server certificate.
a certificate authority (CA) certificate, by whom the client and server certificates
were issued.
The client needs:
The client certificate installed in the Personal Certificates store.
The CA certificate installed in the Trusted Root Certification Authorities store.
What do I give the server from the client and where does it go?
The server needs:
The server certificate installed in the Personal Certificates store.
The CA certificate installed in the Trusted Root Certification Authorities store.
The client certificate installed in the Trusted People store.
Detailed Answer
In this scenario (communication between web farm and self hosted web services), you own both client and server machines. There is no need for third-party issued certificates (you trust yourself, right?). Which means you can safely use home-made certificates.
Here is a quick guide I hope will help you (or someone else), achieve this. If you already own certificates as your question suggests, feel free to skip step I. Furthermore, you may already have bought third-party issued certificates, in that case the root certificate authority (VeriSign, Microsoft, etc) certificate may already be installed on your client and server machines.
I. Create certificates
As explained in this msdn article, use makecert to generate 3 certificates:
A root certificate authority certificate, let's call it MyRootCA, and its revocation list.
A server SSL certificate. The name must be the domain name your web farm clients will use to call the web services. For example, if your clients use the following url: https://mywebserver.myprivatedomain.com/service1.svc, then your certificate CN (Common Name) will be mywebserver.myprivatedomain.com.
A client X.509 certificate, let's call it MyAmazonClient.
Here is a simple batch that achieves those 3 steps:
REM 1: MyRootCA
makecert -n "CN=MyRootCA" -r -sv "MyRootCA.pvk" "MyRootCA.cer"
makecert -crl -n "CN=MyRootCA" -r -sv "MyRootCA.pvk" "MyRootCA.crl"
REM 2: mywebserver.myprivatedomain.com
makecert -sk "mywebserver.myprivatedomain.com" -iv "MyRootCA.pvk" -n "CN=mywebserver.myprivatedomain.com" -ic "MyRootCA.cer" -sr LocalMachine -ss My -sky exchange -pe
REM 3: MyAmazonClient
makecert -sk "MyAmazonClient" -iv "MyRootCA.pvk" -n "CN=MyAmazonClient" -ic "MyRootCA.cer" -sr LocalMachine -ss My -sky signature -pe
This batch will create 3 files in the current folder:
MyRootCA.cer: contains the public key of the root CA certificate.
MyRootCA.crl: contains the certificate revocation list.
MyRootCA.pvk: contains the private key of the root CA certificate.
The 2 other certificates (client and server) are installed in local computer certificate store.
Using the Certificates MMC Snap-in, export them into .pfx files:
Locate LocalMachine > My > Certificates.
Right click MyAmazonClient > All Tasks > Export.
Right click mywebserver.myprivatedomain.com > All Tasks > Export.
II. Install server certificates
On your server machine (the one exposing the web services), copy the following files:
MyRootCA.cer
MyRootCA.crl
MyAmazonClient.pfx
mywebserver.myprivatedomain.com.pfx
Using the Certificates MMC Snap-in on the server machine, install the certificates in the following locations:
MyRootCA.cer and MyRootCA.crl into Local Computer > Trusted Root Certification Authorities > Certificates
MyAmazonClient.pfx into Local Computer > Trusted People > Certificates
mywebserver.myprivatedomain.com.pfx into Local Computer > Personal > Certificates
Grant your IIS AppPool access to the private key of the mywebserver.myprivatedomain.com certificate. In MMC Certificates Snap-in, right click mywebserver.myprivatedomain.com > All Tasks > Manage Private Keys... Then add the identity your AppPool is running with. Note than when using ApplicationPoolIdentity (by default), identity name is IIS AppPool\YourAppPoolNameHere.
III. Configure IIS to support SSL
Using IIS Manager, locate your website and add an https binding with your mywebserver.myprivatedomain.com certificate. See Step 4: Configure Your Temporary Service Certificate in IIS to Support SSL.
IV. Configure the services (web.config)
<system.serviceModel>
<protocolMapping>
<add scheme="https" binding="wsHttpBinding" />
</protocolMapping>
<bindings>
<wsHttpBinding>
<!-- configure wsHttp binding with Transport security mode and clientCredentialType as Certificate -->
<binding>
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
V. Install client certificates
On each client machine (web farm), copy the following files:
MyRootCA.cer
MyRootCA.crl
MyAmazonClient.pfx
Using the Certificates MMC Snap-in on the client machines, install the certificates in the following locations:
MyRootCA.cer and MyRootCA.crl into Local Computer > Trusted Root Certification Authorities > Certificates
MyAmazonClient.pfx into Local Computer > Personal > Certificates
Grant your IIS AppPool access to the private key of the MyAmazonClient certificate (same steps as II).
VI. Configure the clients (web.config)
<system.serviceModel>
<client>
<!-- this endpoint has an https: address -->
<endpoint address="https://mywebserver.myprivatedomain.com/service1.svc"
behaviorConfiguration="endpointCredentialBehavior"
binding="wsHttpBinding"
bindingConfiguration="Binding1"
contract="MyWebApp.IServiceContract"/>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="endpointCredentialBehavior">
<clientCredentials>
<clientCertificate findValue="MyAmazonClient"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<!-- configure wsHttpbinding with Transport security mode
and clientCredentialType as Certificate -->
<binding name="Binding1">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
And that's it.

Related

Fabric access with client certificate auth fails

We're using Fabric secure cluster and need client certificate for CI/CD tools.
I've created both Cluster primary certificate and client certificate with this script https://gist.github.com/kagarlickij/d63a4061a1066d3a85abcc658f0856f5
so both have been uploaded to the same Kay vault and both have been installed to local keystore on my machine.
I've added client certificate to my Fabric security settings (Authentication type = Admin client, Authorization method = Certificate thumbprint).
The problem is that I can connect (I'm using Connect-ServiceFabricCluster in PowerShell) to Fabric cluster with Cluster primary certificate but can't with Client certificate.
I'm getting this error: Connect-ServiceFabricCluster : FABRIC_E_SERVER_AUTHENTICATION_FAILED: 0x800b0109
Please advice what can be done?
Based on this link the corresponding error code for 0x800b0109 is:
A certificate chain processed, but terminated in a root certificate
which is not trusted by the trust provider.
You're using a self-signed certificate as client cert. I'm not sure it's supported as explained in the Service Fabric Security documentation, moreover you'll have to make sure the SSL certificate has been added inside your local Store.
Client X.509 certificates
Client certificates typically are not issued by a third-party CA.
Instead, the Personal store of the current user location typically
contains client certificates placed there by a root authority, with an
Intended Purposes value of Client Authentication. The client can use
this certificate when mutual authentication is required. Note
All management operations on a Service Fabric cluster require server certificates. Client certificates cannot be used for management.
I had the same issue managing my cluster through powershell, I only had 1 cert on the cluster (the one azure generates when creating the cluster) and I believe it is a client cert since I have to select it in my browser when managing the cluster.
Ultimately I had to add the self signed cert to my Root certificate store (in addition to my personal store where I already had it) to get the powershell module to stop complaining about it.

Trusted Root Certificate Automatically disappear on client SSL connection

I have this weirdest problem. First off: I'm VERY new to this certificate thingy. I've done a fair amount of searches and reading up though.
The CA Cert that I install into the Trusted Root Certificate
Authorities store in my server automatically get removed/disappeared
as soon as a client web-browser try to connect to a web-site using an
SSL cert created with that CA cert.
DETAILS:
Windows Server 2008 R2 (development server).
I've created my own Certificate Authority Cert; which I use it to generate an SSL server cert (to install on my IIS 7 Server) and a client cert (for use at my local PC to connect to the WCF Webservice on the development server which is set to Require SSL and Require Client Cert).
I installed the CA Cert into the Trusted Root on both Server and local PC.
Installed the SSL server cert into the IIS7 for that particular site and did the https binding to port 443.
As soon as I launch my browser to access that site with HTTPS, the CA
cert in automatically removed on the server (from the Trusted Root
Certificate Authorities store). and my local PC browser will report
an error 403.
This is driving me nuts... anyone knows what is happening?
Apparently, after a lot of running around, it is due to too many of the same certs in many stores.
I open the MMC.exe > Add/Remove SnapIns > Certificates
Notice there are 3 types there (My User Account, Service Account & Computer Account).
Open up My User and Computer Account, go through all the stores for each one and DELETE all of the CA cert with the same name. Then add the CA cert in either My User Account or Computer Account, depending on how you access the certs (in the event of the cert being used programatically, install it in the Computer Account, [Trusted Root Certificate Authorities].
Just 1 place, then the problem will dissappear.

Mutual Auth in Jboss vs WebSphere

I'm working on Jboss 5 and WAS 7.
I was able to run my application via Mutual Authentication on Jboss following this doc,
https://community.jboss.org/wiki/SSLSetup/
Following the above doc I created server.keystore and server.truststore files that I injected into the Jboss server and everything works fine.
Now, I want to run the same application via Mutual Auth on WAS.
On WAS, the trust store and keystore are specified by navigating to
Security > SSL certificate and key management > SSL configurations > New > Key
stores and certificates
But there I don't see any type related to .keystore and .truststore.(snap below)
My question - what is the equivalent of .keystore and .truststore that can be used in WAS OR what's the way to set up a Browser based Mutual Authentication on a WAS server.
I'm using WAS 7.0.0.21.
Keystores and truststores are the same format in WebSphere. You choose the file format, but any of those formats can be used for either store.
You then point a configuration at specific files.
Security > SSL certificate and key management > Manage endpoint security configurations
Alternatively, what has been simpler for us is to use the existing default stores WebSphere already has and add our certificates to those.
Security > SSL certificate and key management > Key stores and certificates > CellDefaultKeyStore
Or CellDefaultTrustStore or NodeDefaultKeyStore, etc.
The link helped me setup SSL on WAS. I just had to add a couple of steps to enable it for Browser based Mutual Authentication.
Since, I had to do a POC hence I'm using Self Signed Certificates.
In a ideal scenario Certificates will be signed by a Certificate Authority and the Certificate of Certificate Authority will be imported to the Trust Store of a WAS Server.
Here are the steps,
Change the password for Default KeyStore and Default TrustStore in WAS
Create a Client Certificate in WAS
Create a Server Certificate in WAS
Export the Client Certificate in PKCS format, e.g. client.p12
Export the Server Certificate in PKCS format, e.g. server.p12
Import the Client Certificate to Default TrustStore
Import the Server Certificate to Default TrustStore
Enable SSL on WAS.
i. Make sure the to select server certificate for both Default server certificate alias and the Default client certificate alias.
ii. In the Quality of protection (QoP) settings, choose Client Authentication as Required.
Create a Web Container Transport Chain with a new SSL port, e.g. 9444.
Add the newly created SSL port to the virtual Host.
Restart the Server.
Import the Client Certificate created in Step 4 client.p12 to the Browser.

How distribute certificates from software company

I would ask for help in this matter.
I work in a software company and we're writing a client-server application (like system of documents circulation). It will be delivered as a complete solution as two distributions: client and server.
One of the requirements is the client and server must exchange information in encrypted form.
We decided to use SSL, but have some questions:
If we use self-signed certificates then we must generate certificate pair on server side, but how does the client know the server certificate? I want to install all required certificates during installation, but the server certificate is defined only on server installation.
If we ship client and server installer with wired server root certificate signed our company certificate in server and client installer - then our company client may create new certificate signed certificate that sign out certificate, that is chain with our company certificate in root - that is bad.
How can we solve this problem?
I want to ship to client 2 distributions: client, server and after installation they may establish secure channel to exchange information and user should not need to install any certificate manually.
Noticeable, this is completely product, we want to sell them to different companies and these companies must have different certificates.

PKI certificate import

When I login to my bank account using https, it's only a server side SSL authentication before I enter my login info. My browser does the server authentication based on the certificate info from the server during SSL session. I did not have to do any manual import of server certificate as a trusted cert into my browser. It just happens at runtime during SSL exchange.
On the other hand, I have also seen applications where one has to manually import the certificate (using keytool for e.g.) when you look into their install guide.
Question is: If the certificate info is exchanged in the beginning of SSL session, each side has enough info to authenticate the other side. Why would some apps require manual import of certs from each other between client and server. Be it either or both side authentication.
ADDITIONAL INFO based on the responses below:
I was referring the scenario where I was installing a commercial software based on client-server model with client side SSL authentication turned ON. I installed the server on machine A and 2 clients on different machines all in my private network. During install, server generates a self-signed certificate locally. So do the 2 clients. Once installation is complete, I was asked to copy the clients' certs to server machine and manually import them as trusted certs. Also, copy the server cert to client machines and do the import into their trusted store. They provided a wrapper tool on top of java keytool to perform the cert import. Why is this manual import necessary here? The client and server will anyway exchange certificate info during SSL handshake and perform the authentication. Again, these are self-signed certs and CA involved here.
Note that a certificate is signed by a certificate authority so it depends on which certificate authorities your browser trusts. If the Web server sends a certificate signed by a certificate authority that’s trusted by the browser/application and the certificate is valid, you shouldn’t get any warnings whatsoever.
On the other hand, if the browser receives a certificate from the Web server and it doesn’t trust the certificate authority that signed that certificate, the browser will take some action — at the very least, it should warn you about this. When you import a certificate from a Web site, you’re essentially telling your browser that you have decided to trust that certificate independently of who signed it.
Edit: The same reasoning applies: The keystore keeps a list of trusted certificate authorities and their corresponding certificates. The whole concept of PKI is to have a hierarchy of trusted CAs that emit signed certificates for other parties. If a certificate is self-signed, there’s no valid trust chain — how will Java know that the certificate hasn’t been forged by an attacker?
You’re assuming that a connection between a client and a Web server is implicitly trusted just because certificates are exchanged during the SSL handshake. What if a man in the middle poses as the Web server and, instead of sending the server certificate, sends his own certificate instead? How would clients know that the certificate received by the man in the middle is not to be trusted? If the certificate is signed by a trusted CA, or if the certificate has been manually added to the keystore as a trusted certificate, the client can check whether it should trust the certificate or not.
An SSL server's certificate has to be "vouched for" by a certificate authority (CA). Your browser (or other program) contains a list of CAs it trusts. If you're using a site that is not certified by one of the standard CAs, then you'd have to import its CA in order for the verification to succeed.
No legitimate site (especially for online banking) should require you to use an "alternative" CA. Only do this for sites where you're not sending super-sensitive data.