Using Secure Socket Layer (SSL) in JDK 1.3 is not as direct as in JDK 1.4. JDK 1.4 introduces SSL as a new integrated feature, but JDK 1.3 needs external packages to support it. If you are still using JDK 1.3 and need to implement projects with SSL, you should install an extension so that you can access SSL-related classes, such as SSLSocket and TrustManager. Let's look at how you can tap into these classes to implement a Java 1.3 application with SSL. Then, we'll walk through some sample server-side code. In the next article, we'll revisit this topic with a look at the client-side code.
What is SSL?
SSL is a protocol to ensure security inside the network, providing an additional layer to the original TCP/IP architecture between the Transport Layer and the Application Layer. TCP, the protocol that SSL is built on, has no capacities for end user identification and encrypted connection. This allows a hacker to fake a user of the communication as well as capture the plain data inside the network. SSL, on the other hand, ensures both the identity of end users and data security with its two subprotocols:
- · SSL record protocol, which defines the format for data transmission
- · SSL handshake protocol, which defines the process during exchanging data
SSL and the JSSE
SSL functionality has been included in Java Secure Socket Extension (JSSE) for Java developers who require secure communication. JSSE is a set of Java packages that are integrated into JDK 1.4 and are optional for older versions of JDK. This set of packages provides basic utilities for key and certificate management and supports cipher suite negotiation, client and server authentication, and RSA cryptography algorithm. These functionalities are necessary to implement a Java application with SSL.
How do you start SSL in Java? If you're using JDK 1.2 or 1.3, you can download JSSE 1.0.3. After downloading the file and decompressing it, you'll find three Java archive files in the decompressed folder: jcert.jar, jnet.jar, and jsse.jar. These files are important libraries to keep in mind.
On your mark
Before you start programming, you must place the package files in a directory that your Java programs can access. There are two methods to doing so. Table A shows you how both methods work, as well as their advantages and limitations.
I'll demonstrate with an example of a Java applet that requires JSSE. The client side (the applet on Web) will connect to the server side with SSL. I recommend the second approach because applet users do not need to download JSSE explicitly.
The example assumes that you understand TCP socket programming in Java. Simply speaking, socket programming requires code on both the server side and the client side.
On the server side, you create a ServerSocket object to open a socket with a port number and call a method accept() to listen and accept any client connection request. You use the getInputStream() method to obtain a DataInputStream object and the getOutputStream() method to obtain a DataOutputStream object. Then, you can employ the DataInputStream object to receive data and the DataOutputStream object to send data.
On the client side, you create a Socket object to open a socket with the server side’s port number and request a connection. Then, you can send or receive data as you do on the server side.
Finally, you should call a method close() to close a Socket object on the client side and to close a ServerSocket object on the server side. Since SSL is based on TCP, their operations are very similar. But there is some difference in socket creation, which I will cover next.
Our example is a simple client-server program with SSL. We'll start our coding on the server side and focus on the important parts.
The java.security package provides the classes and interfaces for the security framework. The javax.net.ssl package, which comes from the JSSE, provides the classes for the secure socket optional package.
This statement prepares to create an object to handle the client’s SSL connection. In socket programming, a Socket object represents one endpoint of a two-way communication connection between two processes on the network. We need to create an object to handle the client side’s information, which will be provided when the client connects to the server on the server side. Thus, configuring a client Socket object is simpler than configuring a server Socket object.
This dynamically registers a Cryptographic Service Provider, which is a set of essential packages to implement engine classes for specific cryptographic algorithms. The engine classes used in JSSE are SSLContext, KeyManagerFactory, and TrustManagerFactory. Let's go through these engine classes briefly.
SSLContext manufactures objects that in turn manufacture Secure Socket objects. Any class that aims to manufacture another class or object is called a factory. This class is initialized with a set of key and trust managers and a source of secure random bytes.
KeyManagerFactory provides a factory for key managers based on a source of key material. Each key manager manages a specific type of key material used by secure sockets. The key material is based on a KeyStore or a provider’s specific sources.
TrustManagerFactory produces trust managers based on a source of trust material. Each trust manager manages a specific type of trust material used by secure sockets. The trust material is based on a KeyStore or a provider’s specific sources.
To use a provider for the above purpose, you must register it. There are two methods for the registration: static and dynamic. For static registration, you can edit the security properties file, java.security. But this method limits the flexibility during deployment. I would suggest using the dynamic registration as shown in the above code. This will add the default provider, SunJSSE, dynamically in runtime and is not permanent.
Listing A creates a server-side socket using a Server Socket Factory that binds a port to the socket (as well as to the local IP in background) and enables supported cipher suites.
Unlike a generic server socket, an SSL server socket must be produced by its factory object due to its complexity. The default factory can be altered by modifying the value of ssl.ServerSocketFactory.provider in the property file java.security, if you're a U.S. or Canadian user. If you aren't, you should stick with the shipped implementation; otherwise, you will get a runtime exception.
As mentioned in the above, SSLSocket is a subclass of Socket and SSLServerSocket is a subclass of ServerSocket. This hierarchy makes sense, as SSL is built on TCP. A socket is bound to a port number so that TCP can identify the process that data targets should be sent to.
The last statement in Listing A constructs a list of supported Cipher Suites. Cipher Suites are a group of varied cryptographic algorithms that are used in authentication between the server and the client, transmitting certificates, and establishing session keys. When a client requests to connect to a server, they will exchange information to negotiate a cipher that both support.
clientSocket = (SSLSocket)thisServer.accept();
The above snippet allows the server socket to listen for a connection. If there is a connection request, after a proper SSL handshake, the socket will accept the connection.
You should now have an idea of how to install JSSE and get the server-side code in place. The next article will cover the necessary client-side configurations you must make before you launch your Java-SSL application.