In See Playing in the Sandbox we discussed the capabilities for invoking cryptographic functions from within Java code. We also stepped through a simple transaction, to show the ways that cryptography can be used in an application.
But, as we concluded at the time, most programmers and application designers would prefer ready-built cryptographic protocols, rather than having to create them from the basic elements of encryption and digital signatures. Secure Socket Layer (SSL) is the most widely used protocol for implementing cryptography in the Web. In this chapter we look at how it can be invoked from within Java.
As the name suggests, SSL provides a secure alternative to the standard TCP/IP sockets protocol. In fact, SSL is not a drop-in replacement because the application has to specify additional cryptographic information. Nonetheless, it is not a large step for an application that uses regular sockets to be converted to SSL. Although the most common implementation of SSL is for HTTP, several other application protocols have also been adapted.
SSL is comprised of two protocols: the record protocol and the handshake protocol. The record protocol defines the way that messages passed between client and server are encapsulated. At any point in time it has a set of parameters, known as a cipher suite, associated with it, which define the cryptographic methods being used. There are a number of cipher suites defined by the SSL standard, with names that describe their content. For example, the cipher suite named SSL_RSA_EXPORT_WITH_RC4_40_MD5 uses:
When the SSL record protocol session is first established it has a default cipher suite of SSL_NULL_WITH_NULL_NULL (no encryption at all). This is where the SSL handshake protocol comes in. It defines a series of messages in which the client and server negotiate the type of connection that they can support, perform authentication, and generate a bulk encryption key. At the end of the handshake they exchange ChangeCipherSpec messages, which switches the current cipher suite of the record protocol to the one that they negotiated (see See The SSL Handshake for Dummies ).
In the case shown in the diagram, only the server is authenticated, so the client does not need to provide a certificate. If client authentication was required, the handshake would be a little longer. The full specification is at http://home.netscape.com/newsref/std/SSL.html.
The advantage of a protocol such as SSL is that it removes the need for the application developer to deal with the nuts and bolts of cryptography. There are two ways in which Java can exploit this function: by using the SSL support built into the browser, or by using an SSL class package.
When a Webmaster wants users of a site to enter an SSL connection, he or she simply codes a hypertext link with a prefix of " https:" in place of "http:". When the user clicks on the link, the browser automatically starts the SSL handshake, connecting to the default SSL port on the server (TCP port 443).
Any relative URL within an SSL page is also retrieved using SSL. For example, an <APPLET> tag could cause the applet bytecode to be encrypted as it passes across the network. More importantly, the user knows that the applet comes from a trustworthy site, because the authentication process in the SSL handshake will have checked the certificate of the server. You will recall that the signature on a JAR file only shows that the creator of the file can be trusted, not the site from which it came (discussed in See Java Gets Out of Its Box ). By delivering a signed JAR file using SSL you can add the extra authentication without the Web site having to re-sign the file.
If an applet wants to read or write data to the server, it can use the URL classes from the java.net package. These allow the applet code to specify the URL of a Web page or CGI program and to receive the output from the URL in an I/O stream. We showed an example of doing this in the NeverEndingFortuneCookie applet in See Never Ending Fortune Cookie Applet (Part 1 of 2) . If we changed the assignment of fortuneURL in that example to use an https: prefix, the browser would automatically retrieve the data using SSL.
Fetching data using the URL technique (above) is a very simple approach, but it limits the applet because client/server communications can only exploit the capabilities offered by CGI (or another, similar, server interface). Even if this is adequate for the function, it imposes some performance overhead. A direct socket connection between client and server allows more sophisticated and responsive applets to be created.
One possibility is to use a package that provides SSL function in a Java class package. IBM Research in Zurich have created such a package, called SSLight, based on their comprehensive cryptographic toolkit for Java. Although this package is for internal IBM use (due in part to license and export restrictions), it can be used for joint projects with IBM customers. Alternatively, toolkits are available from other vendors.
In the SSLight package the context information for the current SSL connection (in other words, the cipher suite details) is maintained in a Java class named SSLContext. The package then provides a set of classes that mirror the java.net socket classes (including SSLSocket, SSLServerSocket and so on). These behave like their java.net equivalents, except that the constructor methods also require an SSLContext among their arguments. This means that it is a relatively simple matter to modify an application that communicates with sockets to use the package.
The tricky part is setting up the SSLContext class in the first place. It requires a key ring which is, conventionally, a file containing a database of keys and certificates. An SSL client always needs a key ring, even if client authentication is not in use, because it has to check the validity of the certificate presented by the server. To perform the check, the client needs the certificate for the CA that signed the server's certificate. The problem with reading a key ring from a file is that normally it is forbidden by the applet sandbox restrictions.
One solution to this lies in signed applets, but that can lead to further problems, due to the differences in implementation that we discussed in See Java Gets Out of Its Box . The SSLight package provides an innovative alternative, by defining an SSLightKeyRing interface. This means that a key ring can be sent imbedded in the Java class files of the applet, thus avoiding the need for disk I/O. How can the applet know that this key ring (and the CA certificates inside it) can be trusted? The answer is to send the applet itself in an SSL URL. The chain of trust from the point of view of the applet is then:
This is not a rigorous chain of trust, but even if the applet does not have strong authentication for the server, it can still establish an encrypted session. In other words, privacy of the data is guaranteed, even if authentication of the server is based on doubtful logic.
The history of the World Wide Web is based on pragmatism. For example, no one would argue that sending uncompressed ASCII text data on sessions that are set up and torn down for every single transaction is efficient in any way. However, this is what HTTP does, and it is very successful. The reason for its success is that it is simple enough to allow many different systems to interoperate without problems of differing syntax. The cost of simplicity is in network overhead and a limited transaction model.
Using cryptography in Java offers a similar dilemma. It is possible to write secure applications using a toolkit of basic functions. Such an application can be very sophisticated, but it will also be complex. Alternatively, using SSL URL connections offers a way to simplify the application, but at the cost of application function. SSL Java packages, such as SSLight, provide a middle way, retaining simplicity but allowing more flexible application design.