Security
Security is a complex topic. In this section, we will demonstrate a few simple aspects of this topic, as it relates to networks. Specifically, we will create a secure echo server. Creating a secure echo server is not that much different from the non-secure echo server that we developed earlier. However, there is a lot going on behind the scenes to make it work. We can ignore many of these details for now, but we will delve more deeply into it in Chapter 8, Network Security.
We will be using the
SSLServerSocketFactory
class to instantiate secure server sockets. In addition, it is necessary to create keys that the underlying SSL mechanism can use to encrypt the communications.
Creating a SSL server
An SSLServerSocket
class is declared in the following example to serve as the echo server. As it is similar to the previous echo server, we will not explain its implementation, except for its relation to the use of the SSLServerSocketFactory
class. Its static getDefault
method returns an instance of ServerSocketFactory
. Its createServerSocket
method returns an instance of a ServerSocket
bound to port 8000
that is capable of supporting secure communications. Otherwise, it is organized and functions similarly to the previous echo server:
public class SSLServerSocket { public static void main(String[] args) { try { SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); ServerSocket serverSocket = ssf.createServerSocket(8000); System.out.println("SSLServerSocket Started"); try (Socket socket = serverSocket.accept(); PrintWriter out = new PrintWriter( socket.getOutputStream(), true); BufferedReader br = new BufferedReader( new InputStreamReader( socket.getInputStream()))) { System.out.println("Client socket created"); String line = null; while (((line = br.readLine()) != null)) { System.out.println(line); out.println(line); } br.close(); System.out.println("SSLServerSocket Terminated"); } catch (IOException ex) { // Handle exceptions } } catch (IOException ex) { // Handle exceptions } } }
Creating an SSL client
The secure echo client is also similar to the previous non-secure echo client. The SSLSocketFactory
class' getDefault
returns an SSLSocketFactory
instance whose createSocket
creates a socket that is connected to the secure echo server. The application is as follows:
public class SSLClientSocket { public static void main(String[] args) throws Exception { System.out.println("SSLClientSocket Started"); SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); try (Socket socket = sf.createSocket("localhost", 8000); PrintWriter out = new PrintWriter( socket.getOutputStream(), true); BufferedReader br = new BufferedReader( new InputStreamReader( socket.getInputStream()))) { Scanner scanner = new Scanner(System.in); while (true) { System.out.print("Enter text: "); String inputLine = scanner.nextLine(); if ("quit".equalsIgnoreCase(inputLine)) { break; } out.println(inputLine); System.out.println("Server response: " + br.readLine()); } System.out.println("SSLServerSocket Terminated"); } } }
If we executed this server followed by the client, they will abort with a connection error. This is because we have not provided a set of keys that the applications can share and use to protect the data passed between them.
Generating secure keys
To provide the necessary keys, we need to create a keystore to hold the keys. When the applications execute, the keystore must be available to the applications. First, we will demonstrate how to create a keystore, and then we will show you which runtime parameters must be supplied.
Within the Java SE SDK's bin
directory is a program titled keytool
. This is a command-level program that will generate the necessary keys and store them in a key file. In Windows, you will need to bring up a command window and navigate to the root directory of your source files. This directory will contain the directory holding your application's package.
Note
On a Mac, you may have problems generating a key pair. More information about using this tool on a Mac is found at https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/keytool.1.html.
You will also need to set the path to the bin
directory using a command that is similar to the following one. This command is needed to find and execute the keytool
application:
set path= C:\Program Files\Java\jdk1.8.0_25\bin;%path%
Next, enter the keytool
command. You will be prompted for a password and other information that is used to create the keys. This process is shown here, where a password of 123456
is used although it is not displayed as it is entered:
Enter keystore password: Re-enter new password: What is your first and last name? [Unknown]: First Last What is the name of your organizational unit? [Unknown]: packt What is the name of your organization? [Unknown]: publishing What is the name of your City or Locality? [Unknown]: home What is the name of your State or Province? [Unknown]: calm What is the two-letter country code for this unit? [Unknown]: me Is CN=First Last, OU=packt, O=publishing, L=home, ST=calm, C=me correct? [no]: y Enter key password for <mykey> (RETURN if same as keystore password):
With the keystore created, you can run the server and client applications. How these applications are started depends on how your projects have been created. You may be able to execute it from an IDE, or you may need to start them from a command window.
Next are the commands that can be used from a command window. The two arguments to the java
command are the location of the keystore and a password. They need to be executed from the root directory of your package's directory:
java -Djavax.net.ssl.keyStore=keystore.jks -Djavax.net.ssl.keyStorePassword=123456 packt.SSLServerSocket java -Djavax.net.ssl.trustStore=keystore.jks -Djavax.net.ssl.trustStorePassword=123456 packt.SSLClientSocket
If you want to use an IDE, then use the equivalent settings for your runtime command arguments. The following one illustrates one possible interchange between the client and the server. The output of the server window is shown first, followed by that of the client:
SSLServerSocket Started
Client socket created
Hello echo server
Safe and secure
SSLServerSocket Terminated
SSLClientSocket Started
Enter text: Hello echo server
Server response: Hello echo server
Enter text: Safe and secure
Server response: Safe and secure
Enter text: quit
SSLServerSocket Terminated
There is more to learn about SSL than what is shown here. However, this provides an overview of the process with more details presented in Chapter 8, Network Security.