The Fifteen Minute Guide to Mutual Authentication
Inevitably, you’ll cry the first time you attempt to configure mutual authentication with SSL (aka two-way SSL). Well, maybe not cry, exactly. Maybe you’ll just squeeze the mouse until it makes cracking sounds. What? You’ve never done that?
Anyway, the problem many people seem to have when the boss tells them to do mutual authentication is that they go into information overload. PKI jargon. JDK tools. Server configuration. Documentation in a million different places. Couple this information overload with the desire to not “screw up” security and you have a good recipe for developer stress.
I’ve noticed that the biggest problem people have in coming to grips with mutual authentication is that they don’t understand the single most important aspect of configuring it. Once they learn the secret, they have an “A ha!” moment and then the rest of the process becomes much, much clearer.
In a nutshell, the secret is trust.
What I intend to do with this post is to show you the basics so that you can have your very own “A ha!” moment about PKI. Also, by the time this post is done you’ll see two-way SSL in action between your browser and WebLogic. I obviously have to skimp on the details of PKI, but if you follow the steps you’ll have two-way SSL working with test server and client certificates. Let’s get to it!
Certificate Authority Basics
I’ll leave the gory PKI details to other sources, but I have to tell you about Certificate Authorities (CAs).
First, go to any web site where you can use https. This could be your bank, Amazon.com, etc. I used GMail.
Double-click on the lock icon which is probably at the lower-right corner of your browser. In Firefox, you’ll see something like the following dialog:
Figure 1. This dialog shows that the certificate presented by the server is trusted by the browser.
The pertinent take-away here is the wording “…verified by Thawte… a certificate authority you trust…” What the dialog is saying is that the certificate sent from the server (GMail) to my browser was signed (i.e., vouched for) by the Thawte CA. (Note that the name of your CA may be different.)
In other words, I trust the CA and because GMail’s certificate was signed by that CA, I trust the GMail certificate by extension.
Why do I trust the Thawte CA? I trust it because all browsers come pre-loaded with the certificates of common CAs. If they didn’t, you’d constantly get prompted about untrusted certificates from the sites you visit.
Before leaving the Firefox dialog, you might want to click on the View button and have a look at the certificate details. Note the Common Name (CN) fields under Issued To and Issued By. Click on the Details tab if you’re bored, but doing so doesn’t count against my fifteen minute limit!
Figure 2 shows graphically what we just talked about:
Figure 2. With one-way SSL, the server passes its certificate and CA chain to the browser. The browser trusts the CA that issued the server certificate.
Essentially, if we trust the server certificate’s issuer, we can establish an SSL link between our browser and the server. This is an example of one-way SSL. One-way SSL simply means that only the server certificate passes from the server to the client but not the other way around. Thus, only the server is authenticated.
When BOTH sides pass certificates to each other to establish an SSL link, we have mutual authentication via two-way SSL. Both sides now know the identity of the other from their respective certificates.
Figure 3 shows what’s required for two-way SSL:
Figure 3. Two-way SSL comprises the one-way scenario along with the browser passing a personal certificate and its CA chain to the server. The server trusts the CA that issued the personal certificate.
The important thing to realize is that, while the conditions for one-way SSL remain, the mirrored conditions also apply. In other words, the server also has to trust the issuer of the client certificate. That’s all there is to it!
Clearly, SSL is all about trust. Mutual authentication just means that both sides must trust each other. All of the PKI documents and all of the server configuration details all boil down to this fundamental idea. Knowing this makes the rest so much easier.
In my very unscientific estimation, trust issues comprise a very large percentage of the problems people have with SSL. When you have problems configuring SSL, the first thing you should do is check the CA certificates.
So much for the “theory.” That wasn’t so bad, was it? Now let’s take the poor man’s approach to configuring mutual authentication with WebLogic. We’ll use the test CA that comes with WebLogic for both the server and client certificates. You wouldn’t do this for a production server but it’s great for keeping this post under ten minutes like the title promises while demonstrating the concepts. Furthermore, the link is still encrypted just the same as using “real” certificates would do.
Here’s an overview of what we’ll do:
- Load the BEA test CA cert into your browser
- Ensure that SSL is configured on the server
- Access a web page to see one-way SSL in action
- Create a client certificate
- Load the client certificate into your browser
- Set the server to require client certificates
- Access a web page to see two-way SSL in action
You can see that we’ll get one-way SSL working before moving on to two-way.
Configuring SSL in WebLogic
1) Load the BEA Test CA Certificate into your Browser
Out of the box, WebLogic will present a certificate signed by the BEA test CA. You’ll need to add that CA certificate to your browser so that the server certificate will be trusted. Note that what you want to add to your browser is the certificate of the CA that issued the server certificate — not the server certificate itself. If you don’t add the CA certificate, SSL will still work but you will be prompted by your browser about an untrusted certificate.
To load the test CA certificate into Firefox, follow these steps:
- Select Tools/Options/Advanced/View Certificates
- Select the Authorities Tab
- Import <BEA_HOME>\weblogic81\server\lib\CertGenCA.der
- Select “Trust this CA to identify web sites”
- Click the OK buttons to close the three windows
The procedure for browsers other than Firefox will be similar.
Your browser will now trust certificates issued from the BEA test CA. Later, when you are done experimenting with the test certificate, be sure to remove the test CA certificate from your browser.
2) Ensure that SSL is Configured on the Server
For one-way SSL to work, your server has to be listening on the SSL port and have a server certificate configured. Depending upon how you built your domain, this may already be done. Let’s check:
In WebLogic Console, navigate to the server node in the applet. (By the way, these steps assume WebLogic 8.1. There’s no applet in 9.x so navigation is a bit different.)
- Click once on the server node
- On the right side, select the General tab
- Ensure that SSL is enabled and note the SSL port. If they are not set, set them now and click Apply.
- Select the Keystores & SSL tab
- Ensure that you are using the DemoIdentity and DemoTrust keystores. (If not, click Change, select Demo Identity and Demo Trust, and click Apply.)
- If you made any changes, restart your server for the changes to take effect
3) Access a Web Page to See One-way SSL in Action
At this point, your server is configured to use a test certificate signed by the BEA test CA. This test CA is trusted by your browser, so SSL should work swimmingly. To try it:
In your browser, navigate to the WebLogic console but use https and the SSL port like this:
Change localhost to the machine name if you know it. Localhost will work assuming the server is on the same machine as the browser, but you’ll probably see a warning upon connection. Also, change the SSL port to the correct number if necessary.
When you access the Console application over SSL, you may get prompted about a Hostname Mismatch or a Domain Name Mismatch. Either way, they both represent the same problem. The problem is that the demo certificate is based upon your machine name. If you choose to accept the warning and continue, SSL will work and you won’t get prompted again during that browser session. If you don’t want to get the warning, use the machine name instead of “localhost.”
If you go beyond the Console login page, the applet will complain about an untrusted certificate and a hostname mismatch. These warnings can be ignored for our purposes here. If you want to fix them, see the previous paragraph for handling the hostname mismatch problem. To fix the trust issue, load the BEA CA certificate into the trust store in your JRE.
If you see the WebLogic Console, one-way SSL is working. What’s better than one-way SSL? Two-way, of course. Let’s get that working…
4) Create a Client Certificate
We’ll use a utility provided by BEA called CertGen to create a client certificate. This certificate will be issued by the BEA demo CA just like the demo server was. When presented to the server as a client certificate, WLS will trust it since we already configured it to trust the demo CA. To reiterate, the server trusts the client certificate issuer, not the client certificate directly.
Run SetEnv.cmd in your domain directory, change to a working directory of your choice, and then use CertGen to create a client certificate as follows:
java utils.CertGen -certfile certfile.cer -keyfile keyfile.key -keyfilepass password -cn Spongebob
See http://edocs.beasys.com/wls/docs81/secmanage/ssl.html#1192198 for more information on CertGen.
Prior to WLS 8.1.4, CertGen had a different set of parameters, so check the documentation if you are not using 8.1.4 or later. The CertGen command creates both the private key and certificate for the user specified as the CN (Common Name). The files are created in DER and PEM formats. Most browsers donâ€™t recognize PEM/DER files so we need to convert the key and certificate into a PKCS #12 file. On the Windows command line, type the following:
java utils.ImportPrivateKey -keystore Spongebob.p12 -storepass password -storetype pkcs12 -keypass password -alias personal -certfile certfile.cer.pem -keyfile keyfile.key.pem -keyfilepass password
See http://edocs.beasys.com/wls/docs81/admin_ref/utils20.html#1184336 from more information on ImportPrivateKey.
5) Load the Client Certificate into your Browser
The procedure for loading client certificates is almost the same as loading the CA certificate:
- Select Tools/Options/Advanced/Security
- Select “Ask me every time” to see the client certificate request
- Click View Certificates
- Select the Your Certificates tab
- Import Spongebob.p12 (the password is “password”)
Click the OK buttons to close the three windows.
6) Set the server to require client certificates
For two-way SSL to work, your server has to be set to request client certificates.
In WebLogic Console, navigate to the server node in the applet.
- Click once on the server node
- On the right side, select the Keystores & SSL tab
- Click on the Advanced Options Show link at the bottom of the page
- Set Two Way Client Cert Behavior to “Client Certs Requested and Enforced” and click Apply
- Restart your server for the changes to take effect
7) Access a web page to see two-way SSL in action
Drum roll, please. Feel the tension? Will it work?
We know that the server certificate is trusted by the browser since the browser trusts the test CA. The server is configured to trust the test CA, too, since it’s using the DemoTrust keystore. If the browser has a client certificate issued from the test CA, all should be well. Let’s try it:
Navigate to the WebLogic Console over SSL as before (https://localhost:7002/console). You should get prompted to supply a client certificate. See Figure 4.
Figure 4. The long-awaited prompt for a client certificate!
The certificate is already selected so just click OK to use it. You should then see the Console login page. You’ll only need to supply a certificate once per browser session.
If you try to access the Console beyond the login page, you’ll get a handful of prompts from the applet. It’s OK — just click through them. You get all of these prompts from the applet because the applet doesn’t have access to the client certificate like your browser does. As a result, it has no certificate to give. The applet will fail to come up but if you see the Console login page then all is well. You wouldn’t have this massive prompting problem with a normal web application.
Congratulations! You now have mutually authenticated SSL working. You can take the rest of the day off.
At this point, you have a working mutual authentication demonstration. You should also have a good understanding that trust is the key to getting SSL working properly. The client must trust the server and vice versa.
It’s also important to understand what you don’t have if you’ve followed these steps:
- Production-quality certificates
- A means of using the client certificate for authentication to your applications
To switch to production-quality certificates you’ll have to use one of the commercial CAs such as Verisign. You might also have a corporate CA that will serve the same purpose. Even a self-signed certificate is OK if the client chooses to trust it, but they’re likely to have to know you before doing so. Do not use the certificates generated by the BEA CA for anything other than demo purposes. An unsecure CA is worse than no CA at all.
At the moment, the client certificate is only used at the socket level — the server does not care WHO the user is, just that the certificate is trusted. You’ll need to use identity assertion to have the certificate information used for application authentication purposes.
Both of these topics will be covered in subsequent posts. Until then, you can learn more about identity assertion by reading The Mysterious CLIENT-CERT. It’s only a high-level overview, though. You can also check the BEA documentation for detailed information.
Post a comment and let me know how the steps in this post worked for you (or not).