ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Secure Your Sockets with JSSE
Pages: 1, 2, 3, 4, 5

Performing Mutual Authentication

In some applications, client authentication is of paramount importance.

So far, we have SecureBrowser and SecureServer running against each other. SecureServer provides its certificate to SecureBrowser and SecureBrowser authenticates SecureServer. Then they set up a secure communication channel. This scenario is still a little one-sided. How does SecureServer know that it is talking to SecureBrowser? That's where mutual authentication comes in.

Creating a Client Certificate

The first thing that we need to do is to create a certificate for our client. This is accomplished using the keytool.

keytool -genkey -keyalg rsa -alias jaworski
Enter keystore password:  12345678
What is your first and last name?
  [Unknown]:  libretto70ct
What is the name of your organizational unit?
  [Unknown]:  Software Development
What is the name of your organization?
  [Unknown]:  Toolery.com
What is the name of your City or Locality?
  [Unknown]:  Chula Vista
What is the name of your State or Province?
  [Unknown]:  CA
What is the two-letter country code for this unit?
  [Unknown]:  US
Is <CN=libretto70ct, OU=Software Development, O=Toolery.com,
 L=Chula Vista, ST=CA, C=US> correct?
  [no]:  y

Enter key password for <jaworski>
        (RETURN if same as keystore password):

I created the above certificate on another computer named Libretto70CT.

The next thing that we need to do is to export the certificate. Again, we'll use the keytool.

keytool -export -alias jaworski -file jj.cer
Enter keystore password:  12345678
Certificate stored in file <jj.cer>

Now, we import the certificate (jj.cer) into a keystore on the server. This keystore will function as the server's truststore.

keytool -import -alias jaworski -file jj.cer
Enter keystore password: 12345678
Owner: CN=libretto70ct, OU=Software Development, O=Toolery.com, L=Chula Vista, ST=CA, C=US
Issuer: CN=libretto70ct, OU=Software Development, O=Toolery.com, L=Chula Vista, ST=CA, C=US
Serial number: 3ae65817
Valid from: Tue Apr 24 21:52:39 PDT 2001 until: Mon Jul 23 21:52:39 PDT 2001
Certificate fingerprints:
    MD5: BA:28:EC:44:B9:01:AA:6A:AF:3B:87:CB:73:26:6A:78
    SHA1: 71:B5:C1:F3:88:78:1E:33:2F:0B:66:60:8D:20:71:E5:6D:89:71:00
Trust this certificate? [no]: y
Certificate was added to keystore

The keystore that is created from the above command is the default keystore named .keystore. Rename it to jssecacerts and put it in the lib/security subdirectory of your java.home directory. This will make your server aware of the client's key.

Modifying SecureServer and SecureBrowser

We want SecureBrowser to present its certificate to SecureServer so that SecureServer can also authenticate SecureBrowser. The change required on SecureServer's part is minimal. Simply change the following line in SecureServer's constructor from

this("SecureServer", "1.0", 443, false);

to

this("SecureServer", "1.0", 443, true);

This turns on mutual authentication in SecureServer.

On the client side, we must tell the underlying SSL implementation which keystore to use and which password to use to access the keystore. This amounts to setting the javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword properties. On my Libretto, the default keystore that was created is named .keystore and is located in the C:\Windows directory. Simply add the following two lines to the bottom of the SecureBrowser constructor.

System.setProperty("javax.net.ssl.keyStore","c:\\windows\\.keystore");
System.setProperty("javax.net.ssl.keyStorePassword","12345678");

Seeing it in Action

All that's left is to restart SecureServer and access it with SecureBrowser. Make sure that you give SecureServer a minute or two to start up. Then startup SecureBrowser on your client machine. (I recommend using separate machines because it simplifies the process of managing keystores and truststores.

java SecureBrowser https://enpower/
THE HEADERS
-----------
KEY: Content-Length
VALUE: 487
KEY: Content-Type
VALUE: text/html
THE CONTENT
-----------
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <title>Welcome to Java Security using JSSE</title>
</head>

<body>
<h1>Welcome to Java Security using JSSE</h1>

<p>This page was securely sent using SSL version 3.0.</p>
</body>
</html>

SecureServer reports the transaction as follows:

java SecureServer
SecureServer version 1.0
SecureServer is listening on port 443.
Accepted connection to LIBRETTO70CT (192.168.1.70) on port 1098.
Received the following request:
GET / HTTP/1.1
User-Agent: Java1.3.0_01
Host: enpower
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
File sent: C:\WINDOWS\Desktop\JSSE\index.htm
Number of bytes: 487
Request completed. Closing connection.

When you are finished with these examples, go back and delete all of the keystores that you've created to keep any trusted certificates from laying around on your system.

Jamie Jaworski is a Java security expert and author, focused on cryptography and such.


Return to ONJava.com.