Book Image

Learning Network Programming with Java

Book Image

Learning Network Programming with Java

Overview of this book

Network-aware applications are becoming more prevalent and play an ever-increasing role in the world today. Connecting and using an Internet-based service is a frequent requirement for many applications. Java provides numerous classes that have evolved over the years to meet evolving network needs. These range from low-level socket and IP-based approaches to those encapsulated in software services. This book explores how Java supports networks, starting with the basics and then advancing to more complex topics. An overview of each relevant network technology is presented followed by detailed examples of how to use Java to support these technologies. We start with the basics of networking and then explore how Java supports the development of client/server and peer-to-peer applications. The NIO packages are examined as well as multitasking and how network applications can address practical issues such as security. A discussion on networking concepts will put many network issues into perspective and let you focus on the appropriate technology for the problem at hand. The examples used will provide a good starting point to develop similar capabilities for many of your network needs
Table of Contents (16 chapters)
Learning Network Programming with Java
Credits
About the Author
About the Reviewer
www.PacktPub.com
Preface
Index

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.