Mutual-authentication with web services

Viewed 41275

Currently, I've been successful implementing Mutual Authentication security so long as the client accesses the website using a web browser, because browsers take care of all the certificate exchange for you. Now I need to create a secure interface with which users can access web services over HTTPS, using the mutual authentication required by the server.

First off, are there any resources anyone knows of that can help me with this? I've looked for quite some time and found nothing. Any other tips anyone can give me on how to go about this?

Secondly, I think my biggest roadblock is my lack of understanding of how to handle certificates. How do I negotiate accepting the server's key and presenting my own key to the server? This is in Java.

4 Answers

For mutual authentication with SSL (aka two-way SSL) outside a browser, you'll need... Well, actually, let's see what you need for one-way SSL first:

  1. A server keystore
  2. A client truststore

The server keystore contains the server's (possibly self-signed) certificate and private key. This store is used by the server to sign messages and to return credentials to the client.

The client truststore contains the server's (self-signed) certificate (extracted from the server keystore into a stand-alone certificate, without the server private key). This is required if the certificate is not signed by a trusted CA for which you already have a certificate in the truststore bundled with the JRE. This step allows to create a chain of trust.

With this, you can implement one-way SSL (the traditional use case).

To implement two-way SSL, you need to make this setup "symmetric" so we'll need to add:

  1. A client keystore
  2. A server truststore

The client keystore contains the client's (possibly self-signed) certificate and private key. This store is used by the client for the same purpose than the server keystore i.e. to send client credentials to the server during the TLS mutual authentication handshake.

The server truststore contains the clients (self-signed) standalone certificates (extracted from the clients keystore into stand-alone certificates, without the clients private key). This is required for the exact same reasons as previously mentioned.

Some resources to help you to generate all this stuff and to implement the final solutions:

If the web service library uses the standard java.net.URL class as an HTTP client, you can set some system properties and the two-way authentication will be handled by the built-in HTTPS support.

The necessary properties are:

  • javax.net.ssl.trustStore: Contains root CA certificates
  • javax.net.ssl.keyStore: Contains client certificate and private key
  • javax.net.ssl.keyStorePassword: The password protecting the client's private key

These settings become the defaults for all SSL connections by the process. If you want finer control, you have to set up your own SSLContext. Whether that's possible with your webservice runtime depends on which runtime you've chosen.

A simple recipe is given in this blog entry.

But I think the real answer may depend on what Java APIs you are using to implement your client-side HTTP interactions. For example, it looks like you would do things a bit differently using JAX-RPC.

Related