站内搜索: 请输入搜索关键词
当前页面: 图书首页 > XML and Java: Developing Web Applications, Second Edition

XML and Java: Developing Web Applications, Second Edition

[ directory ] Previous Section Next Section

14.3 SSL/TLS

Secure Sockets Layer is defined by Netscape Communications Corporation for securing HTTP connections. Because SSL is implemented in Netscape's browsers, it has become a de facto standard for secure HTTP connection. Today, virtually all browsers and HTTP servers support SSL. The current version of SSL is 3. Based on SSL version 3, the Internet Engineering Task Force (IETF, http://www.ietf.org/) defined Transport Layer Security 1.0. TLS 1.0 is almost identical to SSL version 3, so in this book we use the expression SSL/TLS to refer to both of them. These protocols use X.509 certificates for authentication.

As we discussed earlier, SSL/TLS provides solutions to three security requirements: confidentiality, integrity, and authentication. Confidentiality is achieved by using a symmetric cryptosystem, such as these.

  • Data Encryption Standard (DES), which has a 56-bit key.

  • RC4, or Ron's Code, which was developed by the famous cryptographer Ron Rivest. Its key length is variable but is normally 40 to128 bits.

Integrity is guaranteed by using a message authentication code (MAC) based on a secure hash function, such as Message Digest 5 (MD5) and Secure Hash Algorithm 1 (SHA-1).

Client authentication is optional in an SSL/TLS connection, but server authentication is mandatory. In other words, the client always knows the server's identity, but in many cases the server does not know the client's.

14.3.1 Server Authentication

Figure 14.1 depicts how SSL/TLS works for authentication. To use SSL, a Web server must acquire a server's digital certificate from a certification authority (CA), a third-party organization that issues digital certificates. A digital certificate guarantees that the public key contained in it belongs to its owner so that the receiver of a digitally signed message can verify the authenticity of the signature. The digital certificate format used in SSL/TLS is X.509, defined by the International Telecommunications Union-Telecommunication Standardization Sector (ITU-T).

Figure 14.1. Authentication in SSL/TLS

graphics/14fig01.gif

When a client connects to a server using SSL/TLS, the client and server first look for the strongest common cryptographic algorithm and agree on it. Then they exchange a symmetric key that is used in the encryption of the message body. The key exchange is done by using public-key cryptography as follows.

  1. The server sends its X.509 certificate containing the server's public key.

  2. The client generates a 48-byte random number, a premaster secret, and encrypts the number using the server's public key. It then sends the encrypted premaster secret to the server.

  3. The server decrypts the encrypted premaster secret using its private key.

  4. The server and the client, sharing the same premaster secret, which cannot be obtained by anybody else, generate symmetric keys for message encryption from the premaster secret and start communicating using the generated keys.

Because only the server that owns the proper private key can decrypt the encrypted premaster secret (and thus generate the proper symmetric keys), the client knows, by decrypting the first encrypted message from the server, that it is in fact talking to the correct server.

14.3.2 Client Authentication

Client authentication is optional in SSL/TLS. Although it is often reasonable for a client to stay anonymous in a communication between a browser and a Web server, in many B2B situations client authentication is critical. Two client authentication methods are popularly used with HTTP.

  • HTTP basic authentication (RFC 2617) combined with SSL/TLS without client authentication

  • SSL/TLS certificate-based client authentication

We discuss both of these in the following two subsections.

Combining HTTP Basic Authentication with SSL/TLS

HTTP basic authentication (RFC 2617) is part of the HTTP protocol specification and is based on userids and passwords. Because both are sent without encryption (they are Base64-encoded but are not encrypted), this is not a secure method of authentication. So it must be combined with SSL/TLS, which provides confidentiality.

When basic authentication with SSL/TLS occurs, the following takes place (see Figure 14.2).

Figure 14.2. HTTP basic authentication

graphics/14fig02.gif

  1. The client connects to the Web server using a URL梖or example, https://www.powerwarning.com/. Note that the protocol used is not http: but https:, which refers to HTTP over SSL/TLS.

  2. When the SSL connection is established, the client knows the server's identity with confidence because of the server's X.509 certificate. However, the server does not know the client's identity, so it replies with a return code of 401, thereby requesting that the client authenticate itself.

  3. The client sends its Base64-encoded userid and password in the HTTP header.

Now, all the data is going through the SSL/TLS connection, so it cannot be stolen during transmission. Also, no malicious server can successfully disguise itself as the original Web server in an attempt to steal the user's password.

Certificate-Based Client Authentication in SSL/TLS

Using SSL/TLS certificate-based client authentication requires that the client obtain an appropriate digital certificate before connecting to a server. To obtain a client certificate, a client must generate a public key/private key pair in its client software. The private key is kept secret in a keystore, and it is usually protected by a passphrase. Then the public key is sent to a CA, and a signed certificate is returned.

The advantage of using certificate-based client authentication over HTTP basic authentication with SSL/TLS is that with the former, it is possible to separate the application and the authentication. That is, the application does not need to maintain a userid/password database. It only needs to verify that the certificate presented by the client is indeed signed by a trusted CA.

Consider the following situation. Suppose our power warning service presented in Chapter 1 cannot attract enough customers by itself, so we decide to partner with nine other companies that provide similar services on the Internet. As a group of service providers, we offer a package deal to our common customers. A customer pays a fixed monthly fee to a designated billing company for accessing ten different services operated by the ten independent companies.

In this case, HTTP basic authentication with SSL/TLS has some drawbacks.

  • Each application must maintain its own copy of the userid/password database. This entails associated security risks.

  • The billing company must notify each company of the addition and deletion of new customers and changes to customers' payment status. In addition, this communication must be secure.

  • The customer must manage ten different passwords (if the same password is used, a dishonest employee of, for example, company A can use your password to access, for example, company B's service in your name).

By contrast, when certificate-based authentication is used, applications do not need to do user administration. Figure 14.3 shows the user presenting its certificate to companies A, B, and C. Because this certificate is issued by the CA, the companies can trust that the user is in fact a legitimate user. Thus they are freed from the burden of the complex and possibly human-intensive task of registering and charging customers.

Figure 14.3. Use of client certificates

graphics/14fig03.gif

14.3.3 Selecting a Public-Key Infrastructure

For a server or a client to be authenticated in SSL/TLS, it must have an X.509 certificate issued by some CA. Issuing certificates involves a set of policies, procedures, and mechanisms for receiving a certificate request, verifying the identity of a requester, signing a certificate, revoking a certificate, and so on. These are collectively called the public-key infrastructure, or PKI. You must decide what PKI to use with SSL/TLS. PKI can be any of the following.

  • Commercial CAs issue certificates for general Internet use. For example, Verisign issues certificates for e-mail and software signing and even provides free, 60-day trial Class 1 certificates for individual users. Anyone who has access to an Internet e-mail address can obtain a Verisign Class 1 certificate. When using this certificate, however, you must be sure that the level of security it provides is sufficient to meet your needs. A Class 1 certificate guarantees that the e-mail address of the certificate owner is unique but does not guarantee anything about the true identity of the certificate owner. Although this level of security might be enough for casual e-mail exchange, it certainly is not for serious e-business uses. Verisign offers other classes of certificates of higher security levels. Class 3 certificates are the ones used in ordinary SSL/TLS Web servers.

  • Outsource PKI to outside vendors. Operating a CA properly is not easy. It requires a highly secure hardware and software installation that is professionally maintained, as well as security policies and auditing rules, among other requirements. Therefore, it is reasonable to outsource the CA operation.

  • Although operating a CA properly is not an easy task, it is relatively easy to set up your own CA using one of the CA software packages. This might be a good choice for trial and educational purposes because you can learn various issues in issuing and revoking certificates. Running a private CA also is a possible choice if your organization is serious about setting up its own PKI that will be used across many different applications.

In any case, it is very important that you document your certification policy that dictates the condition of issuing and revoking certificates.

14.3.4 Configuring a Server and a Client for SSL/TLS

Now, let us show you how SSL/TLS can be deployed in a Java-based B2B application. Because software supporting SSL/TLS is becoming popular, most of what you need to do to secure your Web application using SSL/TLS is to configure your software correctly according to your policy.

Configuring a Server

Because certificate-based server authentication is mandatory in SSL/TLS, the first thing you need to do in configuring a server for SSL/TLS is to obtain a server certificate. We assume that you have already decided which PKI to use. To obtain a server certificate, you follow these steps.

  1. Generate a private key/public key pair in the server's key-management software.

  2. Send the public key along with the identity information of the server owner (or operator) to the CA. You might be required to send an official document verifying this identity.

  3. Once the CA is satisfied with the requester's identity and the fact that the key was generated by the requester, it creates a certificate that binds the requester's distinguished name (DN) to the public key by signing the certificate. The signed certificate is sent back to the requester.

  4. The server administrator installs the certificate in the server software.

Next, depending on the client authentication method, you need to do one of the following:

  • Configure the server's basic authentication.

  • Install the trusted CA's certificate that is used for verifying client certificates for certificate-based client authentication.

In the case of using HTTP basic authentication for client authentication, the same authentication mechanism that is used for controlling access to Web pages can be used for authenticating requesters to B2B applications. In Apache Web Server, the most popular HTTP server and also an HTTP frontend of many popular application servers, an access control file named .htaccess contains a reference to an authentication database. In the Tomcat application server we introduced in Chapter 10, a file named conf/tomcat-users.xml is used as the authentication database. An authentication database can be a flat file if the number of users is small, but you need to use a more efficient database when the number of users is large or the same database needs to be shared by multiple servers. Apache Web Server provides a few options with respect to the authentication database. The module mod_auth_dbm allows a large database by means of UNIX's standard database API. The module mod_auth_ldap, although available only in Apache Web Server version 2, can be used for centralizing many authenticating databases into a single directory.

When you use SSL/TLS certificate-based client authentication, no authentication database is necessary. Instead, the server needs to be configured so that only client certificates that are issued by a trusted CA are accepted. This is done by installing the certificate of the trusted CA in the server's keystore.

Configuring a Client

To configure a client for SSL/TLS, first you need to install the certificate of the CA that issues the certificates of the servers to which you intend to connect.

When HTTP basic authentication is used for client authentication, no additional configuration is necessary, but the client program has to explicitly embed a userid and password into an HTTP header.

When SSL/TLS certificate-based client authentication is used, you need to create a public key/private key pair and, in the same process for obtaining the server certificate, ask your CA to issue a certificate for the key and install the certificate into your keystore.

Preparing Keys for the Samples in This Chapter

As we have seen, using SSL/TLS requires processes such as generating a key pair, requesting a certificate, and installing a certificate. Unfortunately, there is no standard tool for performing these tasks. The way these tasks are performed is largely dependent on your server software, client middleware, and the PKI you use. For the reader's convenience, we created a set of keys and certificates that are used in the sample programs in this chapter. The tools we used are keytool, which comes with Java 2 SDK, and OpenSSL, a popular, open source cryptography package. Figure 14.4 shows the relationships between these keys and certificates along with the filenames where these keys and certificates are stored.

Figure 14.4. Keystores used in this chapter

graphics/14fig04.gif

For the selection of PKI, we take the third approach (operating a private CA) that we discussed in Section 14.3.3. XML & Java Test CA is the name (more precisely, the distinguished name, or DN) of our CA that issues all the certificates used in our samples. (This is a private CA that we created specifically for evaluating the sample programs in this book and should never be used for production.) All the keystores have the certificate of this CA as a trusted entry. We used OpenSSL for creating the CA key pair and its certificate. The CA key is in the file chap14/ keystore/cakey.pem, while the CA certificate is in the file chap14/keystore/cacert.cer.

In Section 14.3.5, we show you a sample client program for making an SSL/TLS connection with HTTP basic authentication. In this connection, the server will be authenticated via an X.509 certificate. For this purpose, the client keystore, chap14/keystore/sslclient.ks, must have the CA certificate as a trusted entry.[3] On the server side, we created a server public key/private key pair (we gave it the key alias sslserver) in the server keystore, chap14/keystore/sslserver.ks. Then we had our CA issue a certificate for this key, and we stored the issued certificate back into the keystore. During these processes, we used OpenSSL for issuing certificates, while using keytool to manage both the client and the server keystores.

[3] In Sun's implementation of JSSE, which we use in Section 14.3.5, the default keystore is located at $JAVA_HOME/jre/lib/security/cacerts. Instead of having a separate keystore for your application, you can install the CA certificate into this default keystore. By default, it contains a set of root CA certificates that are commonly used for Web servers.

We also prepared keys for executing the sample programs for XML Digital Signature, which we cover in Section 14.4. We created keys for signature and verification, which are stored in the keystores chap14/keystore/signature.ks and chap14/keystore/verification.ks, respectively.

The accompanying CD-ROM contains all the keys ready for use. We also included on the CD-ROM a detailed explanation of how you can build these keys from scratch using OpenSSL and keytool.

14.3.5 SSL/TLS Programming in Java

Now let us look at how we can use SSL/TLS from our Java programs.

Java 2 Cryptography Architecture

First, let us briefly touch on the Java 2 cryptography packages. Collectively, they provide application programs with a very flexible way to select and use cryptographic algorithms. We review three such packages.

  • Java Cryptography Architecture (JCA) is a basis for Java 2's cryptography functions. It defines the architecture of separating the API and specific implementations as well as the API for the digital signature and digest function. JCA has no encryption API, so it is not subject to the export regulations of the United States.

  • Java Cryptography Extension (JCE) is an optional package that provides encryption APIs.

  • Java Secure Socket Extension (JSEE) is an optional package that implements SSL/TLS using JCA and JCE.

The latter two packages may be missing in a standard distribution of Java 2. If so, you need to obtain these packages and install them into $JAVA_HOME/jre/lib/ext.

The use of cryptography technologies is sometimes restricted by government policies. For example, the United States poses certain restrictions on exporting strong encryption technologies (for example, symmetric cipher cryptosystems with a key length of 128 bits or more). To minimize the impact of such policies on application programs, Java 2 employs a provider architecture, which provides a common set of APIs with pluggable implementation modules, called crypto service providers. Usually, an application does not need to specify which crypto service provider is to be used. Instead, available providers are registered in a configuration file, $JAVA_HOME/jre/lib/security/java.security, as shown next, and the Java cryptography library will select from these the most appropriate provider for a given request.[4] In this example, a JCA provider called sun.security.provider.Sun, a JCE provider called com.sun.crypto.provider.SunJCE, and a JSSE provider called com.sun.net.ssl.internal.ssl.Provider are configured.

[4] In Windows, the configuration file is %JAVA_HOME%\jre\lib\security\java.security.

   :
 security.provider.1=sun.security.provider.Sun
 security.provider.2=com.sun.crypto.provider.SunJCE
 security.provider.3=com.sun.net.ssl.internal.ssl.Provider
   :

You can also configure other providers. If you want to use IBM's implementations, the configuration file will look like this. The number after security.provider. represents the priority of the provider when the library selects one.

   :
 security.provider.1=sun.security.provider.Sun
 security.provider.2=com.ibm.crypto.provider.IBMJCE
 security.provider.3=com.ibm.jsse.JSSEProvider
   :

A provider can also be dynamically added at runtime by executing the java.security.Security.addProvider() method like this.

java.security.Security.addProvider(new com.ibm.jsse.JSSEProvider());

However, this technique should not be used unless there is a good reason to do so, because hardcoding a crypto service provider will constrain the environments in which your application can be executed.

Using Java Secure Socket Extension

JSSE provides a socket-equivalent API for SSL/TLS. Therefore, once an appropriate keystore is properly configured, using JSSE is fairly straightforward. The following is a snippet of Java code for calling JSSE.

import javax.net.ssl.*;
      :
    SSLSocketFactory factory
             =(SSLSocketFactory)SSLSocketFactory.getDefault();
    SSLSocket socket = (SSLSocket)factory.createSocket("demohost", 8443);

The class SSLSocket is a subclass of java.net.Socket, so a socket created this way can be used as if it is an ordinary socket.

If the protocol being used is HTTPS梩hat is, an HTTP protocol over SSL/TLS?it is simpler to specify https as the protocol in a URL. When creating a URLConnection object, instead of calling the following:

URLConnection uc = new URL("http://www.abc.com/").openConnection();

you can call this:

URLConnection uc = new URL("https://www.abc.com/").openConnection();

One catch is that this feature is not part of the JSSE specification. But most implementations, including Sun's reference implementation, support this feature. When you run a program using this feature, you need to set a special protocol handler to the system property java.protocol.handler.pkgs. You can do this by adding the following option in a command line when executing the java command.

-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol

You also need to specify what keystore you want to use in the command line. The option you need is as follows. The keystore password, changeit in our prefabricated keystores, should be changed to the password of your keystore.

-Djavax.net.ssl.trustStore=./chap14/keystore/sslclient.ks
-DtrustStorePassword=changeit

Listing 14.1 shows a simple client program that sends an HTTP GET request to a server using an SSL/TLS connection with HTTP basic authentication. The use of SSL/TLS is specified by using a URL starting with https:. For HTTP basic authentication, the supplied userid and the password are concatenated using a colon (:) as a separator; then the concatenated string is Base-64 encoded and added as an HTTP header named Authorization.

Listing 14.1 Client using HTTP basic authentication with SSL/TLS, chap14/ SSLClientWithHTTPBasicAuth.java
package chap14;
import java.net.URL;
import java.net.URLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class SSLClientWithHTTPBasicAuth {
    public static void main(String[] args) throws Exception {
        String url = "https://demohost:8443/xmlbook2/chap14/index.html";
        if (args.length > 0) url = args[0];
        String userid = "tomcat";
        if (args.length > 1) userid = args[1];
        String passwd = "tomcat";
        if (args.length > 2) passwd = args[2];
        URLConnection uc = new URL(url).openConnection();
        sun.misc.BASE64Encoder base64enc = new sun.misc.BASE64Encoder();
        String auth =base64enc.encodeBuffer(
                       (userid+":"+passwd).getBytes("UTF-8")).trim();
        uc.setRequestProperty("Authorization","Basic "+auth);
        BufferedReader ins = new BufferedReader(
                                new InputStreamReader(uc.getInputStream()));
        String line;
        while ((line = ins.readLine()) != null) {
            System.out.println(line);
        }
        ins.close();
    }
}

To run this program, you must include the system properties that we mentioned earlier in the command line as follows. Note that the command line is broken into multiple lines for readability, but they must be typed in a single line.

 R:\samples>java
-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol
             -Djavax.net.ssl.trustStore=./chap14/keystore/sslclient.ks
             -DtrustStorePassword=changeit
             chap14.SSLClientWithHTTPBasicAuth

14.3.6 Firewall Considerations

When SSL/TLS is used for B2B communication, you should consider how your firewalls are configured, as your server is probably located behind the firewall that restricts TCP connections in a certain way. A typical firewall configuration is depicted in Figure 14.5, where the SSL/TLS server is sitting in a network segment bracketed by a pair of firewalls. This network segment, which is isolated from both the Internet and the intranet, is called the Demilitarized Zone (DMZ).

Figure 14.5. SSL server located in the DMZ

graphics/14fig05.gif

One firewall of the DMZ is facing the Internet and accepts certain connections from the Internet to a selected set of servers in the DMZ. The other firewall, facing the intranet, usually blocks all the inbound connections. Both of the firewalls allow outbound connections for popular Internet applications, such as HTTP for Web browsing. This configuration implements the policy "Selected DMZ hosts are accessible from the Internet, but no hosts in the intranet are accessible from the Internet, even if some host in the DMZ is compromised." With this configuration, all the SSL/TLS connections must terminate at the SSL/TLS server in the DMZ. If the server needs to communicate further with some host in the intranet, a separate connection needs to be established.

There are two ways to connect the SSL/TLS server in the DMZ with a host in the intranet. One is to allow inbound connections from the SSL/TLS server to the intranet host by carefully configuring the inner firewall so that it only allows connections between the specific pairs of hosts on a specific port. The other way is to prohibit all the inbound connections and let the intranet host make an outbound connection every time the connection is required.

14.3.7 Summary of Using SSL/TLS

We have looked at how we can use SSL/TLS for securing our B2B communications. Most of the task involves understanding the available options, selecting the ones that satisfy your security policy, and configuring the software accordingly. The programming part is very small.

Because SSL/TLS-enabled Web sites are very popular, many companies let their firewalls allow HTTPS (port 443) connections. Therefore, an application sitting inside a company's firewall can have a direct secure connection to another company's server using SSL/TLS. It is said that in the United States, more than 50% of network crimes are committed from inside a firewall. Given this fact, the end-to-end security achieved by SSL/TLS has a large value.

    [ directory ] Previous Section Next Section