| ★ wanayoo — archive 1999 http://java.oreilly.com/bite-size/java_1099.html | Nouvelle recherche | Portail wanayoo |
|
||
|
|
Secure Sockets Layer (SSL) is a widely implemented and accepted standard for making network communications more secure. One of the reasons it's nice is that it presents a shrink-wrapped solution to the problem of secure network communications. Behind the scenes, a lot of tricky cryptographic stuff is going on, but you don't have to worry about it. SSL has been around for five years; it's solid, tested technology. SSL was originally developed by Netscape; the current version is SSLv3. SSL is standard equipment in web servers and browsers. If you've ever paid for anything on the Internet using a credit card, chances are you've already used SSL; web pages whose URLs begin with https are transmitted to your browser using SSL. SSL is a staple of electronic commerce. SSL and Java seem like a natural match. After all, Java has excellent cryptography and security infrastructure. RSA, Phaos, and other companies have sold third-party SSL packages, but until recently, there was no standard API for using SSL from Java. That's all changed with the early access release of the Java Secure Socket Extension (JSSE). Basically, the JSSE defines an API for using SSL and other technologies like SSL. An implementation of SSL is bundled with the JSSE, although Sun makes it clear that it's only for reference, and you'll probably want to buy somebody else's implementation of the JSSE. Our examples make use of this reference implementation; as long as you write code that conforms to the JSSE API, your programs should work with anyone's JSSE implementation. The JSSE is available at the Java Developer Connection. The JSSE is distributed as a zip file. It unzips into a main directory and two subdirectories, doc and lib. To install the JSSE, copy the JAR files from the lib directory to the jre/lib/ext directory underneath your Java SDK main directory. This is the place where all standard extensions live. On my system, for example, I copied the JAR files from the JSSE to \jdk1.3\jre\lib\ext directory. You'll also need to register the SSL cryptographic provider with the Java runtime system. To do this, edit the /jre/lib/ext/security/java.security file with a text editor. Scroll down to the part that lists security providers (you should see a line that begins "security.provider.1=..." Add the JSSE provider with a line like this: security.provider.2=com.sun.net.ssl.internal.ssl.Provider The JSSE defines classes and interfaces in the javax.net and javax.net.ssl packages. The reference implementation is distributed in the com.sun.net.ssl package. Additionally, certificate support is provided in the javax.security.cert package. This package is only necessary with JDK 1.1 and before. Java 2 supports the java.security.cert package, which is nearly identical. The Good NewsThe good news is that using SSL can be very easy. As a matter of fact, the JSSE is designed so that SSL networking is just as easy as regular networking in Java; the SSLSocket and SSLServerSocket classes work almost exactly like the familiar Socket and ServerSocket classes.Normally, you would connect to a remote system with code like this: Socket s = new Socket("www.usps.gov", 80); This line of code creates a new connection to www.usps.gov on port 80. After the connection is established, you can use the streams returned by getInputStream() and getOutputStream() to send and receive data to the remote computer. If you've already worked with Sockets in Java, this will be very familiar stuff. What if you wanted to add some security to garden variety network communications? SSL makes it hard for an eavesdropper to observe the conversation on a network connection. Here's how you can create an SSL-enabled connection: Socket s = SSLSocketFactory.getDefault().createSocket("www.usps.gov", 443); In the first example, we just used java.net.Socket's constructor to create a new Socket instance. Here, we use an instance of javax.net.ssl.SSLSocketFactory to create a Socket. The call to SSLSocketFactor.getDefault() returns a factory object that knows how to create SSL-enabled sockets. The call to createSocket() tells the SSLSocketFactory to create an SSL-enabled connection to the given host and port number.The returned object is a subclass of Socket, javax.net.ssl.SSLSocket. If you're willing to accept the default SSL options, you can simply treat the returned object as a Socket, as we have above. If you'd like to take advantage of the additional methods in the SSLSocket class, you can cast the returned object to an SSLSocket. That's all there is to it--the rest of your code can remain the same. The first time data is exchanged on an SSLSocket, it performs some SSL magic to encrypt the data passing through the network. Keep reading to find out more about the magic. About SSLSSL is a protocol that runs on top of a normal TCPIP connection. When you first open up a network connection, SSL goes through a process called handshaking. Basically the two ends of the network connection negotiate to decide how they will encrypt the rest of the conversation. They exchange information about what cryptographic algorithms they have. With a little luck, the two sides have a common set of algorithms that can be used to encrypt the rest of the communication.Handshaking is performed by an SSLSocket when you first try to send or receive data over the network connection. If you prefer, you can explicitly kick off handshaking by calling the startHandshake() method. SSL also includes the capability to authenticate one or both sides of the conversation. However, this is an optional feature and not generally used in https web sites. SSL without authentication is called anonymous SSL. Cipher SuitesThe set of algorithms that are used for the SSL conversation is called a cipher suite. The cipher suite is composed of several cryptographic algorithms:
import java.io.*;
import javax.net.ssl.*;
public class PrintSession {
// What's the cipher suite?
The output is a long string like this: SSL_RSA_WITH_RC4_128_MD5 This tells you that RSA is used for key exchange, RC4 (with a 128-bit key) is the encryption algorithm, and MD5 is the message digest algorithm used to ensure integrity. To find out the list of cipher suites that are supported by your implementation of SSL, call the getSupportedCipherSuites() method in SSLSocket. Of these cipher suites, only the ones returned by getEnabledCipherSuites() will be used for handshaking. You can modify the list of enabled cipher suites by calling setEnabledCipherSuites(). Just Let Me Know When It's OverHandshaking may take a while to complete. On my Pentium II 266MHz, for example, it takes 10 or 15 seconds to negotiate a cipher suite and set up the encryption key. If you would like to know when handshaking is complete, you can register an event listener on the SSLSocket, like this:
import java.io.*;
import javax.net.ssl.*;
public class Handshake {
// Add a handshake listener.
In this simple example, an anonymous inner class is created as an event handler for HandshakeCompletedEvents. When the handshake is complete, a message is printed out. The event object itself contains some useful information; here, the cipher suite is printed out. To Whom Am I Speaking?SSL does also include the capability for authentication. In other words, each side of the SSL conversation can tell the other side who it is in a cryptographically secure way. This is accomplished through the use of cryptographically signed certificates. When you use SSL to retrieve a web page, for example, the web server may present you with a list of certificates verifying its identity. This list is called a certificate chain; each certificate verifies the one before, until you get to a top-level certificate that is issued by a trusted Certificate Authority.You can obtain the certificate chain from an SSLSocket's session, like this:
import java.io.*;
import javax.net.ssl.*;
public class ShowCertificates {
// Who's there?
This program creates an SSLSocket, then obtains the certificates from the session object. (Handshaking is started automatically when we ask for the session object.) We loop through each certificate in the chain and print it out. In this particular case (www.usps.gov), two certificate are returned. The first certifies the identity of the USPS web server and is signed by RSA, a Certificate Authority. The second certificate is RSA's self-signed certificate. Assuming you trust RSA's certificate, you can now be reasonably sure that you are talking to a server that belongs to the US Postal Service. HTTPSJava's networking library has some nifty extensions that make it easy to deal with web content. For example, you can retrieve text and images from the web very simply using a URL object. Instead of having to know the details of HTTP, you simply create a URL and ask for its contents, like this:
URL u = new URL("http://www.usps.gov/");
InputStream in = (InputStream)u.getContent();
In this case, the URL's getContent() method returns an InputStream representing a web page. With the JSSE, it's just as simple to use HTTPS, which is HTTP over SSL. All you need to do is tell the networking system how to handle URLs that begin with https. This is accomplished by setting the value of a system property:
System.setProperty("java.protocol.handler.pkgs",
Together At LastThe formal union of Java and SSL has been a long time coming. Finally, the JSSE standardizes Java access to SSL services. Networking in Java is pretty smooth going; now secure networking in Java is smooth going too. In this column, I've covered the basics:
Download the source code.
Jonathan Knudsen is an author and developer at O'Reilly & Associates. He is the author of Java Cryptography, Java 2D Graphics, and The Unofficial Guide to LEGO® MINDSTORMS Robots.
O'Reilly Home | O'Reilly Bookstores | How to Order | O'Reilly Contacts International | About O'Reilly | Affiliated Companies © 1999, O'Reilly & Associates, Inc. |
|