WS-Security using Cert Authentication with Spring-WS III: Setting up the Security infrastructure

The Story so far

In the first episodes, we configured Spring-WS for rejecting incoming Messages which were sent from ‘unauthorized’ Clients, including the demand for Clients to be trusted by our WebService Endpoint: We only trust in a Client, if its Certificate is in turn issued by a Signer we trust. In our case, the Clients Certificate have to be issued by a Certificate Authority (CA) we trust. We inform Spring-WS about that trusted CA by importing the CAs Certificate into our Truststore (a common Java Keystore), which is declared as the Truststore to check against within Spring-WS’ application context.

In other words, we trust all Client Certificates which are directly issued by the CA which itself is trusted by
the Service Endpoint (by providing its Certificate in the WebServices Truststore). This ‘Chain of Trust’ is going to be validated for every Client’s Certificate (by trying to build a so called Certificate Chain) whenever a Client is transmitting an appropriate Request Message to our WebService.

Certificate Authority … again

As we’ve already mentioned, the Certificate Authority is an ‘entity’, which issues Certificates for use by other parties. Within this role, it kind of acts like an autonomous, accepted party which all participants rely on. Although there are some commercial CAs (like VeriSign or Thawte Digital Certificates) we are free to come up with an own CA.
Let’s say, we want to create a custom CA, ‘representing’ the Host of our WebService, e.g. a CA which is commonly used by the Company which provides the WebService (so to say a Companies own CA). All potential Clients of that WebService have to ask to be signed by that Companies CA (we’ll get back to that task called ‘Certificate Signing Request’ in a further episode, when switching to the client side) in order to be recognized as an accredited Client who is allowed to access the Companies WebService.

OpenSSL

The following sections will give some step by step instructions on how to build your own CA using OpenSSL and importing the CAs Certificate into Spring-WS’ Truststore afterwards. In this regard, this episode is not too strongly related to Spring-WS but rather serve as a general approach on setting up a CA Key-Pair as a vital part of a custom Security infrastructure (sometimes called PKI – Public Key Infrastructure).

Before we start to create the CAs Key-Pair, we have to install OpenSSL (i will show how to do so for Windows, but the
steps are very similar on a unix based operating system). If not done yet, you first have to download and install OpenSSL (you might get a download of a precompiled win version via this site – you may also have to download the ‘Visual C++ 2008 Redistributables’ fom the same site should you detect and need to fix some problems under Windows …)

Certificate Factory

Next, we’ll build an appropriate folder structure where we’ll initially create and store our CAs private Key and the related Certificate (holding the associated public Key). We’ll extend that structure in some following sessions in order to store some more data like Certificate Signing Requests and the like.

I’ll use [CERTFACTORY_HOME] for an arbitrary folder of your choice as the root folder for our structure to build:

[CERTFACTORY_HOME]\ca
[CERTFACTORY_HOME]\ca\certs
[CERTFACTORY_HOME]\ca\crl
[CERTFACTORY_HOME]\ca\newcerts
[CERTFACTORY_HOME]\ca\private

Groundwork

Next, we have to place some files, which are needed by OpenSSL for properly creating a new CA:

  • Create a new (empty) Textfile named index.txt under [CERTFACTORY_HOME]\ca
  • Copy file serial from [OpenSSL_HOME]\bin\PEM\demoCA to [CERTFACTORY_HOME]\ca
  • Copy OpenSSLs Master-Configuration-File openssl.cfg from [OPENSSL_HOME]\bin directly to [CERTFACTORY_HOME]

OpenSSL Configuration

The file openssl.cfg serves as OpenSSLs Master-Configuration. Here we have to configure OpenSSL in order to create a CA according to our whiches. For this purpose we’ll append a new configuration section that should be used whenever
we want to create a new CA, defining some defaults on where OpenSSL should place the generated Keys, which input data to use and some settings used for building the CAs certificate:

[ WEBSERVICE_CA ]

dir   = ./ca
certs   = $dir/certs
crl_dir   = $dir/crl
database  = $dir/index.txt
new_certs_dir  = $dir/newcerts
certificate  = $dir/cacert.pem
serial   = $dir/serial
crlnumber  = $dir/crlnumber
crl   = $dir/crl.pem
private_key  = $dir/private/cakey.pem
RANDFILE  = $dir/private/.rand
x509_extensions  = usr_cert
default_days  = 365
default_crl_days = 30
default_md  = sha1
preserve  = no
policy   = policy_anything

[ policy_anything ]
countryName  = optional
stateOrProvinceName = optional
localityName  = optional
organizationName = optional
organizationalUnitName = optional
commonName  = supplied
emailAddress  = optional

Note, that we named our new section WEBSERVICE_CA (of course you are free to come up with a name of your own).
The only thing left is to link to our customized configuration section as the configuration to use whenever a new CA should be created via this configuration file. This is done some lines above within section [ ca ], where we now will link to our section as the default configuration:

[ ca ]
default_ca = WEBSERVICE_CA

Look … it’s a … new CA

We’re now ready to create our custom CA. Make sure that [OpenSSL_HOME]\bin is on your path, so that you’re able to
invoke OpenSSL from everywhere from the command line. Now, switch to [CERTFACTORY_HOME]> (where we’ve placed our adapted configuration file) and start to build your own CA by typing the following command:

openssl req -x509 -newkey rsa:1024 -keyout ca\private\cakey.pem -out ca\cacert.pem -config openssl.cfg

You will be asked to give some relevant information related to the new CA (like some organisational data and a pass phrase for restricting access to the CAs Key-Pair – you’re asked for it again, at least when signing some Client Certificates with the CAs private Key at later time). After you’ve answered the questions appropriately, you’ll find the new CAs public Key (embedded within an accordant Certificate) under [CERTFACTORY_HOME]\ca\cacert.pem and the related private Key under [CERTFACTORY_HOME]\ca\private\cakey.pem.

Note, that the created Certificate is supplied in so called PEM-Format – in order to import it into a Java-Keystore, we have to convert it accordingly:

openssl x509 -outform DER -in ca\cacert.pem -out ca\cacert.cert

Now if you take a look at [CERTFACTORY_HOME]\ca, you’ll find the converted Certificate with the specified name cacert.cert.

Storing Trust

Now let’s come up with a new Java-Keystore which will serve as the before mentioned Truststore for Spring-WS (used by our Security Interceptor, or better by the injected KeyStoreHandler). We’ll use Java’s keytool for that purpose, so be sure to have [JAVA_HOME]\bin on your path.
Unfortunately, if using keytool you can’t create a new Keystore without also creating a new Key-Pair initially, which is automatically embedded within the new Keystore. As we don’t need this Key-Pair within our Truststore (we only need the CAs Certificate within), we’ll provide a Dummy which we’ll delete afterwards. It’s a good idea to initially place that Java-Keystore within our folder structure, so we might create another separate folder for storing our Truststore, like [CERTFACTORY_HOME]\truststore. After switching to that new folder, we’re ready to go:

keytool -genkey -alias dummy -keyalg RSA -keystore truststore.jks

Again you have to answer some questions, related to the new Keystore (like the password to securely refer to the Keystores content or getting permission to import some other Certificates), again some organisational data belonging to the initial Key-Pair and an associated individual passwort.
As you may have seen, the initial created Key-Pair is ‘labeled’ by an alias Name (the name to uniquely refer to that Key-Pair within the Keystore) called dummy, which we’ll use immediately to delete the dummy Key-Pair:

keytool -delete -alias dummy -keystore truststore.jks

Now we’re ready to import the (already converted) Certificate of our trusted CA:

keytool -import -file ..\ca\cacert.cert -alias trustedCA -keystore truststore.jks

Know the Score

We’re ready to go with our newly created Trustore (containing the Certificate of our also newly created custom CA) now. The only thing left is to place the Keystore accordingly, so that Spring-WS is able to refer to it at runtime within your deployed environment. If you remember the first episode, we already configured Spring-WS for that purpose:

<bean id="trustStore"
      class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
<property name="location" value="/WEB-INF/MyTruststore.jks"/>
<property name="password" value="MyJavaKeyStorePassword"/>
</bean>

As you see, we have to make sure that our Keystore will be deployed under /WEB-INF using the Name MyTruststore.jks (Spring-WS needs to run within a Web-Container, as it’s front controller / message dispatcher is a Servlet). Of course you also have to keep the property password in sync with the password you’ve assigned to the Keystore (while we created it).

Summary

OpenSSL allows for the creation of new Certificate Authorities. We created a custom CA which will serve as the WebServices entity to trust. Now, all Client Certificates, which will arrive within incoming request messages have to be signed by that new CA. We said so by importing the CAs Certificate into a newly created Java-Keystore, which have to be provided as the Truststore, which is refered by Spring-WS’ Security Interceptor (more precisely, the KeyStoreHandler, which gets called by the Security Interceptor).

In the next episode, we’ll switch to the client side and see how to come up with a Client’s private Key and a related Certificate which gets signed by our CA. We’ll then implement a WebService-Client that will sign its request messages
in accordance to our claimed security policies (also using Spring-WS) and call our secured WebService.

Advertisements

2 Responses to “WS-Security using Cert Authentication with Spring-WS III: Setting up the Security infrastructure”

  1. WS-Security using Cert Authentication with Spring-WS IV: How to set up your Clients’ Keystore « brain driven development Says:

    […] (after we made sure that the client behind that request is a trustworthy one). Following up the last episode, we’ll extend the folder structure within our ‘Certificate Factory‘ by creating a […]

  2. Vinod Says:

    Thank you for simplified and detailed explanation. Keep posting.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: