Java Q&A

How do you ensure secure communications from a Java applet? Kenneth and Thomas show how, using HTTPS tunneling for SSL security.



June 01, 1998
URL:http://www.drdobbs.com/jvm/java-qa/184410589

Java Q&A

Kenneth is a senior software engineer for American Management Systems. Thomas is a technical architect in the corporate banking practice at American Management Systems. They can be contacted at kenneth_ [email protected] and thomas_ [email protected], respectively.


One of the significant features of Java is its simple implementation of networking classes. This streamlined but powerful collection of classes lets Java applets easily open sockets to servers and transmit data. Ensuring that the data transmitted over a socket is safe from prying eyes is not as simple, however.

The Secure Sockets Layer (SSL) protocol, developed by Netscape, is the de facto standard for sending encrypted data over the Internet. SSL provides a platform-independent way to secure data transmitted from one machine to another. On the Web, safe communications are denoted by the HTTPS protocol (meaning that a server listens for data with an SSL socket). This ensures that all communications between the browser and web server are encrypted, and that the server has been authenticated. In a case where web browsers have a certificate to prove the identity of its user, SSL also provides for client-side authentication.

Java applets can implement SSL in two different ways. The most obvious, and more difficult, way is to acquire an implementation of the SSL protocol written in Java. This implementation would provide a Secure Socket class that would operate in the same manner as a standard Java Socket, only the data would now be encrypted before transmission. While relatively simple from a technical standpoint, this option requires buying a commercially available Java implementation of SSL, and getting the appropriate licensing for distribution over the Web. Furthermore, the web browser needs to download the Java class files for the Secure Socket every time the applet is run, adding to the time it takes for the applet to start up. In addition, the code to perform these services is already provided by the web browser. This code is written in a native compiled language and has been time tested for optimal performance. Supplying this functionality in Java is inefficient and repetitive.

The second, less obvious, option utilizes the Secure Socket functionality already built into web browsers and web servers by tunneling proprietary data over the HTTPS protocol. Tunneling is the process of transmitting data of one protocol type by wrapping it in a stream of a second protocol.

At American Management Systems, we've experimented with HTTPS tunneling to pass data from a Java applet to an application server and determined that its benefits include:

Digging a Secure Tunnel

There are three aspects to the tunneling process you need to consider -- the Java Applet Client, Proxying Service, and Application Server.

Java Applet Client. The applet client is responsible for instructing the browser to send data over the HTTPS URL. The listener will receive data that is posted to the URL https://Servlets/ProxyServlet. HTTPS URLs basically function like regular sockets as a means to transmit data, with these exceptions:

Once these considerations are made, URL connections can operate just like regular sockets. A program can retrieve an output stream to send data and an input stream to read the response.

Listing One is an applet that opens a URL connection using the HTTPS protocol. The applet sets the appropriate parameters on the connection object, sends the string, and reads and prints out the response. Listing Two (ClientExample.html) calls the applet from within an HTML document.

Proxying Service. One of the security features of the Java environment is that downloaded applets can only communicate back to the machine from which they were downloaded. This makes it impossible for a Java client to communicate directly to any server sitting anywhere outside of the web server. A proxying service must be created to intercept the data on the web server and forward it onto a predefined server, facilitating the communications between the client and the server. This service is responsible for:

The proxy service can be implemented utilizing any native web server plug-in facility such as CGI, NSAPI on Netscape Servers, ISAPI on Microsoft IIS, or the Java Servlet API. This implementation uses a Java Servlet installed on the web server. Figure 1 shows how the Client/ProxyServlet/Server interact. The client POSTs the data to the ProxyServlet URL (https://Servlets/ProxyServlet) and waits for a response. The web server is configured to pass this data into the Java ProxyServlet for processing. The ProxyServlet URL decodes the posted data, creates a socket connection through a firewall to the Application Server, transmits the data over the socket, and waits for a response. The firewall is configured to allow communication only between the web server and the Application Server to secure the data behind the firewall. The Application Server receives the request data, processes the request, and sends the response data back to the ProxyServlet. The ProxyServlet receives the response data and returns it as a response to the POST. The Java Client Applet receives the response to the URL request and processes the response.

ProxyServlet.java and ServerConnection.java (available electronically; see "Resource Center," page 3) implement the Java ProxyServlet. This implementation will create a new connection to the Application Server for each client request. The Servlet.properties file (see Listing Three) contains parameters for serverPort and serverAddress. These parameters configure the destination TCP/IP address of the application server. An enhancement to this architecture would be to add a connection manager that would maintain a pool of connections to the application server. This enhancement would remove the overhead of creating a new connection to the Application Server for each request that is processed, thus improving performance.

Application Server. The Application Server is a standard TCP/IP server implementation. The Application Server listens on a defined port, receives the request data over the socket, processes the request and creates response data, then passes this data back over the socket. This is a common architecture, and examples can be easily found that are implemented in Java or C++.

Issues

This solution is not 100 percent pure Java because of its reliance on the browser's implementation of the HTTPS protocol. Since all of major browsers support the secure protocol, this is not a serious issue.

Current limitations in Microsoft's Internet Explorer 4.0x cause problems when a Java applet uses URL Connections. This problem can be alleviated by disabling the HTTP 1.1 option on either the browser or the web server. (This issue may already be resolved by the time you read this.)

Conclusion

While using the socket classes provided by Java for communications can be simple, when introducing real-world issues, such as security and firewalls, their usability can fall short. HTTPS tunneling provides SSL security and consideration for firewalls. When contrasted with a Java implementation of SSL, tunneling over HTTPS decreases your code size and provides significant performance improvement.

DDJ

Listing One

/* ClientExample.java -- @version 1.0 * @author American Management Systems
 * Opens a connection to the specified URL using the HTTPS protocol
 * sends data that is passed as a parameter then reads the server response
 */


import java.applet.*; import java.net.*; import java.io.*;

public class ClientExample extends Applet {

//The instance of the url connection private URLConnection urlConnection;

/** Starts the applet this is called every time the page is reloaded */ public void start() { System.out.println("ClientExample sends data to a server using HTTPS POST"); String data = getParameter("Data");

send(data); read(); } /** This is called to send the data over a new URL */ public void send(String data) { try { System.out.println("Data: " + data);

//URL encode the data to the x-www-form-urlencoded MIME format String urlEncodedData = URLEncoder.encode(data); System.out.println("URL Encoded Data: " + urlEncodedData);

//Instance the URL (protocol, host, port) String protocol = getCodeBase().getProtocol(); int port = getCodeBase().getPort(); String host = getCodeBase().getHost(); URL url = new URL(protocol, host, port, "/servlet/ProxyServlet"); System.out.println("Destination URL: " + url.toString());

//Open the connection urlConnection = url.openConnection();

//Turn off the caching feature urlConnection.setUseCaches(false);

//Set the URL to POST instead of GET urlConnection.setDoOutput(true);

//Set necessary properties urlConnection.setRequestProperty("content-type", "application/x-www-form-urlencoded"); urlConnection.setRequestProperty("content-length", String.valueOf(urlEncodedData.length()));

//Get the output stream and send the data PrintStream outStream = new PrintStream(urlConnection.getOutputStream()); outStream.println(urlEncodedData); outStream.close(); System.out.println("Data sent successfully"); } catch(Exception e) { System.out.println("URL Connection error: " + e.toString()); } }

/** This is called to read the response from the server */ public void read() { try { //Get the input stream from the connection object DataInputStream in = new DataInputStream(new BufferedInputStream(urlConnection.getInputStream())); //Read a line of data String response = in.readLine(); System.out.println("Server response: " + response); } catch(IOException e) { System.out.println("Error reading from input stream " + e.toString()); } } }

Back to Article

Listing Two

<html><head>
<title>ClientExample</title>
</head>


<body> Check to the java console for output <hr>

<applet code=ClientExample.class width=40 height=40> <param name=Data value=ClientExample data> </applet>

<hr> </body> </html>

Back to Article

Listing Three

servlet.ProxyServlet.code=ProxyServletservlet.ProxyServlet.initArgs=serverPort=4321,serverAddress=127.0.0.1

Back to Article


Copyright © 1998, Dr. Dobb's Journal

Java Q&A

How Do I Ensure Secure Communications from a Java Applet?

By Kenneth Golomb and Thomas Sorgie

Dr. Dobb's Journal June 1998

//URL encode the data to the x-www-form-urlencoded MIME format
String urlEncodedData = URLEncoder.encode(data);
System.out.println("URL Encoded Data: " + urlEncodedData);
//Instance the URL (protocol, host, port)
String protocol = getCodeBase().getProtocol();
int  port = getCodeBase().getPort();
String host = getCodeBase().getHost();
URL url = new URL(protocol, host, port, "/servlet/ProxyServlet");
System.out.println("Destination URL: " + url.toString());
//Open the connection
urlConnection = url.openConnection();
//Turn off the caching feature
urlConnection.setUseCaches(false);
//Set the URL to POST instead of GET
urlConnection.setDoOutput(true);

Example 1: HTTP URLs function like regular sockets.


Copyright © 1998, Dr. Dobb's Journal

Java Q&A

How Do I Ensure Secure Communications from a Java Applet?

By Kenneth Golomb and Thomas Sorgie

Dr. Dobb's Journal June 1998

Figure 1: How the Client/ProxyServlet/Server interact.


Copyright © 1998, Dr. Dobb's Journal

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.