Use JSSE to customize the properties of SSL connection — reprint

JSSE provides secure communication for Java applications by encrypting and protecting data over the network using SSL. In this advanced research on this technology, Ian Parkinson, a Java middleware developer, deeply studied the less known aspects of JSSE API and demonstrated how to program around some limitations of SSL. You will learn how to dynamically select keystore and truststore, relax the password matching requirements of JSSE, and build your own customized keymanager implementation.

JSSE (Java secure socket extension) enables Java applications to communicate securely over the Internet using SSL, because developerWorks has provided a tutorial covering the basic usage of JSSE (see), so this article will focus on the more advanced use of this technology. This article will demonstrate how to customize the properties of SSL connections using the JSSE interface.

First, we will develop a very simple secure client / server chat application. As we build the client side of the program, I'll demonstrate how to customize keystore and truststore files to load them from the client's file system. Next, we will focus on certificates and identities. By selecting different certificates from keystore, clients can be provided to different servers in different forms. This advanced feature is particularly useful if your client application needs to connect to multiple peers, or even if it needs to impersonate different users.

Since this article focuses on more advanced topics, it is assumed that you already have experience with JSSE. To run the example, you need a Java SDK with the JSSE provider properly installed and configured. The J2SE 1.4 SDK provides the installed and configured JSSE. If you are using J2SE 1.2 or 1.3, you need to get a JSSE implementation and install it. See downloading JSSE extensions.

JSSE API is only a standard of J2SE 1.4, and there are slightly different variants between early JSSE implementations. The examples in this article are based on the 1.4 API. If necessary, I will highlight the changes necessary to make the example work with the sun JSSE implementation of J2SE 1.2 and 1.3.

Before we dive into JSSE, let's familiarize ourselves with the client / server application we're going to use. Simplesslserver and simplesslclient are two components of our demo application. To run the example, you need to set up several keystore and truststore files on each end of the application. In particular, you will need a keystore file for the client called clientkeys, a keystore file for the server called serverkeys, and a truststore file for the client called clienttrust, The certificate containing the server is called servertrust. The truststore file for the server contains the certificates of Alice and Bob. Next, download the attached file. These files contain the source code and compiled versions of the client / server application, so just put them in classpath and you can use them. To run simplesslserver, We enter the following (slightly lengthy) command: you can see that we have specified the keystore to identify the server and the password set in the keystore. Since the server will require client authentication, we have also provided it with truststore. By specifying truststore, we ensure that sslsimpleserver will trust the certificate provided by sslsimpleclient. Server initial After initializing itself, you will get the following report: after that, the server will wait for a connection from the client. If you want to run the server on another port, specify - port XXX at the end of the command and replace the variable XXX with the selected port. Next, set up the client components of the application. Enter the following command from another console window: by default, the client will attempt to connect to the server running on the local host port 49152. You can change the host using the - host and - port parameters on the command line. When the client has connected to the server, you will get a message: at the same time, the server will report the connection request and display the distinguished name provided by the client, as shown below: in order to test the new connection, try to enter some text into the client, press return, and observe whether the server echoes the text. To kill the client, press ctrl-c on the client console. The server will record the disconnection as follows: there is no need to kill the server; We just need to keep the server running during various exercises. Although the rest of this article focuses on client applications, it's still worth looking at the server code. In addition to understanding how the server application works, you can also learn how to use the handshakecompletedlistener interface to retrieve information about SSL connections. SimpleSSLServer. Java starts with three import statements, as follows: javax net. SSL is the most important of the three statements; It contains most of the core JSSE classes that we will use to handle any SSL related work. java. security. CERT is useful when you need to manipulate a separate certificate (which we will do later in this article). Java.io is a standard Java I / O package. In this case, we will use it to process data received and sent through a secure socket. Next, the main () method checks the optional - port parameter in the command line. Then it obtains the default sslserversocketfactory, constructs a simplesslserver object, passes the factory to the constructor, and starts the server, as shown below: since the server runs on a separate thread, as long as it starts and runs, main () exits. The new thread calls the run () method, which creates an sslserversocket and sets up the server to require client authentication, as follows: after it is activated, the run () method performs an infinite loop and waits for requests from the client. Each socket is associated with the handshakecompletedlistener implementation, The latter is used to display distinguished names from client certificates (DN). The InputStream of the socket is encapsulated in an inputdisplay, which runs as another thread and echoes the data from the socket to system.out. The main loop of simplesslserver is shown in Listing 1: our handshakecompletedlistener -- simplehandshakelistener provides an implementation of the handshakecompleted () method. When the SSL handshake phase is completed, the method is called by the JSSE infrastructure, We use this method to get and display the DN of the client, as shown in Listing 2: if you are running the simplesslserver application on J2SE 1.2 or 1.3, you need to use a slightly different method (and now obsolete) JSSE API. Instead of importing java.security.cert, javax.security.cert is used. The package also contains a class called x509certificate; however, in order to obtain the certificate object array from handshakecompletedevent, the getpeercertificatechain() method must be used instead of the getpeercertificates() method. The lines highlighted in red are two very important lines: getpeercertificates returns the certificate chain as an array of x509certificate objects. These certificate objects establish peer (that is, the identity of the client). The first in the array is the client's own certificate; the last is usually the CA certificate. Once we have the peer's certificate, we can get the DN and display it to system.out. X509certificate is defined in the package java.security.cert. The first client application we will study can't do anything at all. But Yes, we will extend it to illustrate more advanced functions in later examples. Simplesslclient is set up to easily add subclasses. We intend to override the following four methods: Main () is, of course, called when running the class from the command line. For each subclass, main () must construct an object of the appropriate class and call the runclient () and close () methods on the object. These methods are provided on the superclass simplesslclient and are not intended to be overridden. Handlecommandlineoption() and displayusage() allow each subclass to add options on the command line without updating the parent class. They are all called from the runclient () method. Getsslsocketfactory () is an interesting method. JSSE secure sockets are always constructed from sslsocketfactory objects. By constructing a custom socket factory, we can customize the behavior of JSSE. For the purposes of future exercises, each simplesslclient subclass implements this method and customizes sslsocketfactory accordingly. Currently, simplesslclient can only understand the - host and - port parameters, which allows the user to point the client to the server. In this first basic example, getsslsocketfactory returns the default factory (JVM wide) as follows: the runclient () method called from the main () method of the subclass is responsible for processing command-line parameters, and then obtains sslsocketfactory from the subclass for use. It then connects to the server using the connect () method and starts transmitting data on the secure channel using the transmit () method. The connect () method is fairly simple. After connecting to the server using sslsocketfactory, it calls starthandshake on the secure socket. This forces JSSE to complete the SSL handshake phase and thus triggers the handshakecompletedlistener on the server side. Although JSSE does start handshaking automatically, it does so only when data is first sent through a socket. Because we will not send any data until the user enters a message on the keyboard, but we want the server to report the connection immediately, we need to use starthandshake to force a handshake. The transmit () method is also fairly simple. Its first task is to wrap the input source into the appropriate reader, as follows: we use BufferedReader because it will help us split the input into separate lines. Next, the transmit () method wraps the output stream -- in this case, the OutputStream provided by the secure socket -- into the appropriate writer. The server wants the text to be encoded in UTF-8, so we can let the outputstreamwriter use the following encoding: the main loop is very simple; As you can see in Listing 3, it looks more like the main loop of inputdisplay in simpleslserver: that's all the basic JSSE server and client code. Now, we can continue to extend simplesslclient and look at some other getsslsocketfactory implementations. Remember how we ran simplesslclient? The command is as follows: the command is too long! Fortunately, this and the following examples will show you how to set up an sslsocketfactory with hard coded paths to keystore and truststore. In addition to reducing the length of the above commands, the technique you will learn will allow you to set up multiple sslsocketfactory objects, each with different keystore and truststore settings. Without this configuration, each secure connection in the JVM must use the same keystore and truststore. Although this is acceptable for smaller applications, larger applications may need to connect to multiple peers representing many different users. For the first example, We will use the sample application customkeystoreclient (can be found in the source code of this article) to dynamically define a keystore. Before studying the source code, let's take a look at the customkeystoreclient in use. For this exercise, we will specify truststore instead of keystore. Enter the following parameters on the customkeystoreclient command line, and we will see the results: assuming that the client is well connected and the service is good The server will report that the certificate provided is valid. The connection was successful because customkeystoreclient Java has hard coded the name (clientkeys) and password of the keystore (password). If you choose another file name or password for the client keystore, you can use the new command-line options - KS and - kspass to specify them. Study the source code of customkeystoreclient.java. The first thing getsslsocketfactory does is call the helper method getkeymanagers(). Later we will consider how this works; At present, it only indicates that it returns the keymanager object array, which has been set with the required keystore file and password. After obtaining the keymanager array, getsslsocketfactory performs some setup work that is usually important for all JSSE customizations. In order to construct sslsocketfactory, the application obtains an instance of sslcontext, initializes it, and then uses sslcontext to generate an sslsocketfactory. When we get the sslcontext, we specify the "SSL" protocol; We can also put a specific SSL (or TLS) protocol version here and force communication to occur at a specific level. By specifying "SSL", we allow JSSE to default to the highest level it can support. The first parameter of sslcontext.init is the keymanager array to be used. The second parameter (left null here) is similar to trustma

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>