Covering J2EE Security and WebLogic Topics

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:

  1. Load the BEA test CA cert into your browser
  2. Ensure that SSL is configured on the server
  3. Access a web page to see one-way SSL in action
  4. Create a client certificate
  5. Load the client certificate into your browser
  6. Set the server to require client certificates
  7. 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:

  1. Select Tools/Options/Advanced/View Certificates
  2. Select the Authorities Tab
  3. Import <BEA_HOME>\weblogic81\server\lib\CertGenCA.der
  4. Select “Trust this CA to identify web sites”
  5. 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.)

  1. Click once on the server node
  2. On the right side, select the General tab
  3. Ensure that SSL is enabled and note the SSL port. If they are not set, set them now and click Apply.
  4. Select the Keystores & SSL tab
  5. Ensure that you are using the DemoIdentity and DemoTrust keystores. (If not, click Change, select Demo Identity and Demo Trust, and click Apply.)
  6. 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:

https://localhost:7002/console

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:

  1. Select Tools/Options/Advanced/Security
  2. Select “Ask me every time” to see the client certificate request
  3. Click View Certificates
  4. Select the Your Certificates tab
  5. 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.

  1. Click once on the server node
  2. On the right side, select the Keystores & SSL tab
  3. Click on the Advanced Options Show link at the bottom of the page
  4. Set Two Way Client Cert Behavior to “Client Certs Requested and Enforced” and click Apply
  5. 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. ;-)

Epilogue

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).

23 Comments

  1. Thank you for these simple steps.
    -satya

    Comment by Satya Ghattu — July 5, 2006 @ 9:41 pm

  2. Hi, Satya. Thanks for stopping by.

    Thank YOU for all the good advice you give in the Dev2Dev forums! You’ve indirectly helped me several times now…

    Mike

    Comment by Mike Fleming — July 5, 2006 @ 10:14 pm

  3. Thanks Mike for this concise but truely demonstrative article.

    I also enjoy reading other articles. well said and presented. They help me a lot in undertanding WLS security/SSL. Thanks again.

    Comment by Suilong — September 21, 2006 @ 3:39 pm

  4. Thanks. This is great. The BEA documentation is like a map showing you all the locations but with no indication of where you need to go. Posts like this are like much needed directions! Keep ‘em coming.

    Comment by Red-3 — October 26, 2006 @ 4:44 pm

  5. Excellent article! I was looking for a simple explanation of MASSL to give to some people and this fits the bill perfectly. *claps*

    Comment by James Turnbull — March 21, 2007 @ 7:27 pm

  6. very good work ..
    Do you know how to configure apache2 and weblogic plugin with 2-way ssl ? I need to use apache2 as fron-end for load balancig and architercural restrictions ..

    thanks.

    Comment by mek — April 19, 2007 @ 11:36 am

  7. Mek,

    To my knowledge, the 8.1 plugin doesn’t support two-way SSL. I don’t know about WLS 9.x.

    Comment by Mike Fleming — April 19, 2007 @ 8:03 pm

  8. hey thanks for the wonderful single page guide .keep blogging :)

    Comment by Sanyam — May 12, 2009 @ 12:45 am

  9. I was wondering that we still hasn’t achieved the true authentication by this. we still have to define a mapping b/w user and certs.
    any commnets?

    Comment by Sanyam — May 12, 2009 @ 5:14 am

  10. Sanyam,

    Thanks for the encouragement!

    Your question inspired me to write “Certificate to User Mapping in WebLogic” (http://monduke.com/2009/05/12/certificate-to-user-mapping-in-weblogic/).

    Thanks, and feel free to comment either here or there if I didn’t answer your question.

    Comment by Mike Fleming — May 12, 2009 @ 9:33 pm

  11. A great post – thank you so much.
    I have some questions –

    if I have two java runtime (exactly duplicate), but in different servers, trying to access a web service using mutual SSL.

    1> do I need DNS name for my client runtime – or I could just give my client any name I like;
    2> do I need to have a certificate for each of my client runtime?

    Thanks

    Comment by Melvin — July 27, 2009 @ 5:08 pm

  12. Melvin,

    Yes, each client needs a certificate to present to the web service. They could even be the same certificate if you wish. It doesn’t matter as long as the web service trusts the signer of the client cert.

    DNS doesn’t matter for the client certificate. In fact, in the article the client certificate is for a user named “Spongebob.” However, a server could have its own certificate such as “bank.com.” It’s very common for middleware to use such certs for client authentication to other services.

    HTH,

    Mike

    Comment by Mike Fleming — July 27, 2009 @ 8:57 pm

  13. Hi,
    Thanks for publishing such a nice article! it was so helpful. I tried to install the client side certificate in the browser and do the required changes in weblogic for two way ssl authentication. Now,when i access https://localhost:7002/console –>it gives me a certificate error
    ————————-
    “The security certificate presented by this website was issued for a different website’s address.

    Security certificate problems may indicate an attempt to fool you or intercept any data you send to the server.”
    —————————
    No warnings display in the console as well :(
    could you please help me on this?

    Thanks,
    asi

    Comment by asi — August 13, 2009 @ 1:27 am

  14. Asi,

    You’ll get that error unless the CN for your certificate happens to be “localhost” which it is not. Basically, it’s working as it should. The browser is warning you that while you requested website “localhost,” the site presented its ID as “abc.com” or whatever your certificate’s CN is.

    To make the error go away you can add an exception (which you normally wouldn’t want to do) or use DNS to route “abc.com” to the machine where you’re running WebLogic. Then, you can go to https://abc.com:7002/console and the browser won’t complain.

    HTH,

    Mike

    Comment by Mike Fleming — August 13, 2009 @ 7:16 pm

  15. Thanks for simplifying a complicated topic. My question:

    What is the best approach for restricting access to your webservice to specific clients only? There seem to be a few options, some more restrictive than others:

    1. Clients use self-signed certs. They share their self-signed certs with us out-of-band and we import them into our truststore. We remove all other certs (CAs, intermediaries) from our truststore, so now only those clients can connect whose end-entity, self-signed certs are in our truststore.

    2. client uses a CA-signed cert. We add the CA to our trust store (if it’s not already there by default). But now anyone with a cert issued by that CA can connect. This is the most basic option.

    3. Our internal CA signs the client’s cert. (The clients submit the CSR to our CA.) Our truststore contains only our internal CA’s cert. So now only those clients can connect that have certs issued by our CA.

    4. The client uses a cert issued by another CA. We add the client’s end-entity cert into our truststore. The truststore doesn’t contain any CA/intermediary certs, it contains only client end-entity certs. Would this even work when our service performs cert path validation, as the end-entity issuing CA certs will not be in our truststore?

    Any suggestions would be appreciated. Thanks!

    Comment by Lee — August 25, 2009 @ 4:43 pm

  16. Lee,

    You’ve laid out your options nicely. One and four are essentially the same, though. If validation is an issue in #4 you could always use your own validator.

    Any of your options will work but there are two other possibilities to consider. The first is to map users to groups and groups to roles. Protect your web service using the roles and then only users in your group are authorized to use the web service. That would solve the anybody-signed-by-the-CA-has-access problem.

    The other option is to have a look at WebLogic’s built-in certificate registry. It’s like a reverse CRL lookup in that only certificates present in the registry are accepted. Here’s a snippet from the WLS docs:

    “The WebLogic Server Certificate Registry is an out-of-the-box CertPath provider that allows the administrator to configure a list of trusted end certificates via the Administration Console. The Certificate Registry is a builder/validator. The selection criteria can be EndCertificateSelector, SubjectDNSelector, IssuerDNSerialNumberSelector, or SubjectKeyIdentifier. The certificate chain that is returned has only the end certificate. When it validates a chain, it makes sure only that the end certificate is registered; no further checking is done.”

    So, really, I think your decision comes down to how do you want to administer users? Adding certs to trust stores requires file system access while a WLS admin can add a user to the registry or a group via WLS Console. If you use an external user store you’d add/remove users as appropriate for the product.

    HTH,

    Mike

    Comment by Mike Fleming — August 25, 2009 @ 8:08 pm

  17. Mike – We were looking at authN based solely on client certs (mapping them to users or roles has to differed). I was hesitant to use self-signed certs, but that may be the best solution out of the four options — a white-list of allowed clients.

    Appreciate your valuable feedback.

    Comment by Lee — August 26, 2009 @ 12:35 pm

  18. [...] IMAP on the iPhone with SSL client certificates Filed under: iphone — Tags: certificate, imap, iphone, ssl — martin @ 11:02 pm The IMAP server in my office is configured to not just accept username/password authenticated connections from the internet. As an additional security measure, it requires the client to present a valid SSL client certificate, issued by the internal CA, resulting in mutual SSL authentication. [...]

    Pingback by IMAP on the iPhone with SSL client certificates « #!/bin/blog — November 12, 2009 @ 5:06 pm

  19. Thanks for this very simple and informative article.

    I need to setup a mutual authentication between Apache 2.2 and Internet Explorer 7.
    I had few questions -
    1. Do we need to buy a browser certificate from one of the ceritification authorities? I just spoke to one of the Experts from a famous Certification authority, but he had no idea what this is all about..

    2. What will the certification authority verify for issuing a certificate to an individual browser?

    3. Can you point me to any resource that explains the process for Apache 2.2 – internet explorer?

    Comment by Prasanna — March 25, 2010 @ 1:10 pm

  20. Prasanna,

    Search the web for how to set up Apache for SSL. It’s reasonably straightforward and CAs usually have configuration guides.

    What you need for the client-side is not so much a browser certificate but rather a personal certificate. Verisign is one CA that offers them if that’s the famous CA you’re referring to. Personal certs can be used in browsers but also in email clients, for example. Personal certs aren’t hard to qualify for — having a credit card in your name should do the trick. ;-)

    Whether or not to buy certs from a commercial CA really depends on what you’re looking to do. For an internal app you could use your own internal CA for issuing server and personal certs. OpenSSL is a barebones way of doing that. If your website is for the masses, however, then using a commercial CA is probably the best choice.

    Hope this helps,

    Mike

    Comment by Mike Fleming — March 25, 2010 @ 7:45 pm

  21. I am still facing problem configuring Mutual SSL for IIS. It gives me forbidden 403 error. Please let me know how to set up it in IIS

    Comment by Vibhu Gupta — April 12, 2010 @ 6:16 am

  22. I have both (Server and Client) Live Site certificate. I feel I don’t need to add to the browser or trusted CA store. I am calling webservice but it’s giving forbidded 403 error.

    Comment by Vibhu Gupta — April 12, 2010 @ 6:37 am

  23. Sorry, Vibhu, but I’m not familiar with IIS.

    Comment by Mike Fleming — April 12, 2010 @ 8:53 pm

Sorry, the comment form is closed at this time.

 

Bookmark this page on del.icio.us