e−commerce. Second, the client already has other credentials that it gives to the server, such as a credit card number, an address, a promise to send a check, and so on. Its easier for the client to
provide these credentials than to obtain a digital certificate in order to operate with an SSL server.
The SSL protocol exchanges several pieces of information between the client and server when the client first connects to the server. This process, known as an SSL handshake , is illustrated in Figure 14−1.
Figure 14−1. Sample SSL handshake
Although there are variations on the way this proceeds and there may be intermediate messages in the protocol, the basic flow of information goes like this:
The client initiates the connection to the server and tells the server which SSL cipher suites the client supports.
1. The server responds with the cipher suites that it supports.
2. The server sends the client a certificate that verifies its identity.
3. The server initiates a key exchange algorithm, based in part on the information contained in the
certificate it has just sent, and sends the necessary key exchange information to the client. 4.
The client completes the key exchange algorithm and sends the necessary key exchange information to the server. Along the way, it verifies the certificate.
5. Based on the type of key exchange algorithm which in turn is based on the type of key in the servers
certificate, the client selects an appropriate cipher suite and tells the server which suite it wants to use.
6. The server makes a final decision as to which cipher suite to use.
7. If the server desires, it can ask for the clients certificate so that it can be assured of who it is talking to; the
client certificate is sent before the client key exchange information if required. Once all this information has been established, the client and server can communicate normally over the socket; data that flows over the
socket will be encrypted automatically.
Programatically, these steps are transparent: a developer asks for an SSL socket, and when the SSL socket is created, the protocol handshake is complete. This is one of the advantages of using SSL. We could have
written all the code to establish the connection, perform the key exchange using code based on the key exchange example we saw in Chapter 10, and encrypt the data using code based on the examples from
Chapter 13, but SSL hides all those details from us. 262
14.1.1 Keystores and Truststores
JSSE introduces the notion of a truststore, which is a database that holds certificates. In fact, a truststore has exactly the same format as a keystore; both are administered with
keytool , and both are represented
programmatically as instances of the KeyStore
class. The difference between a keystore and a truststore is more a matter of function than of programming construct, as we will see.
The server in an SSL conversation must have a private key and a certificate that verifies its identity. The private key is used by the server as part of the key exchange algorithm, and the certificate is sent to the client
to tell the client who the server is. This information is obtained from the keystore. Remember from our key exchange example in Chapter 10 that the private key is never sent from the server to the client; it is used only
as an input to the key exchange algorithm.
SSL servers can require that the client authenticate itself as well. In that case, the client must have its own keystore with a private key and certificate.
The truststore is used by the client to verify the certificate that is sent by the server. If I set up an SSL server, it will use a certificate from my keystore to vouch for my identity. This certificate is signed by a trusted
certificate authority or, as weve seen, there may be a chain of certificates, the last of which is signed by a recognized CA. When your SSL client receives my certificate, it must verify that certificate, which means
that the trusted CAs certificate must be in your local truststore. In general, all SSL clients must have a truststore. If an SSL server requires client authentication, it must also have a truststore.
In sum, keystores are used to provide credentials, while truststores are used to verify credentials. Servers use keystores to obtain the certificates they present to the clients; clients use truststores to obtain root certificates
in order to verify the servers certificates.
The keystore and truststore can be and often are the same file. However, its usually easier to manage keys if they are separate: the truststore can contain the public certificates of trusted CAs and can be shared easily,
while the keystore can contain the private key and certificate of the local organization and can be stored in a protected location. In addition, JSSE is easier to use if the keystore contains a single alias. When the keystore
contains multiple aliases there are ways to specify which one should be used, but that requires more programming. Well show that programming later in this chapter, but keep in mind that in general a keystore
containing a single alias makes using JSSE simpler.
Keystores and truststores are managed programmatically by classes that implement the KeyManager
and TrustManager
interfaces. Well look into those interfaces later, but for now well use their default implementations. The default trust manager assumes the public certificates are held in
JREHOMElibsecurityjssecacerts. If that file doesnt exist, it assumes they are held in JREHOMElibsecuritycacerts. As weve seen, this file contains the root certificates of several well−known
CAs, so it is a good choice. If you want to provide a different truststore, you can set the system property
javax.net.ssl.trustStore to the name of the desired file note that this property is not a URL, so
you can only load it from a local file. The default implementation of the key manager does not use a default keystore; it has no notion of
HOME.keystore. To use the default key manager, you must set the javax.net.ssl.keyStore
property to the name of the desired keystore. In addition, you must set the javax.net.ssl.keyStorePassword
to the password for the desired keystore. The password in this case must be the same for both the keystore itself and the private key entry that you want to use.
For the most part SSL uses RSA keys, and those are the type of keys and certificates you need in your keystore and truststore. This is not an absolute requirement; SSL is actually very flexible about the types of
key exchange and encryption algorithms it supports, and if you communicate only between JSSE servers and clients, you can use DSA keys. However, most browsers understand only RSA−based algorithms, so if youre
writing a server that a browser will talk to, you need an RSA key.
In the examples in Chapter 10, we created a keystore with an RSA key. Well use that keystore for the examples in this chapter, and well export the certificate from that keystore to use as the truststore. Here are
the steps to do that:
Create an RSA key for the keystore. See Chapter 10 for information on the genkey
option to keytool
to do this. You can get a CA−issued certificate for this key if you want, but the examples in this chapter will work with the default self−signed certificate.
1. Export the RSA certificate without the private key:
piccolo keytool −export −alias sdo −file test.cer Enter keystore password:
Certificate stored in file test.cer
2.
Import the RSA certificate into a new file the truststore. This allows us to recognize the issuer of the certificate as a valid CA. If you got a CA−issued certificate, you can use the
trustcacerts option
to accept the certificate automatically. Were storing the truststore in HOME.truststore ; on Microsoft Windows, you might substitute C:\WINDOWS\ .truststore or any other file you like.
Heres how to import the certificate:
piccolo keytool −import −alias test −keystore HOME.truststore −file test.cer Enter keystore password:
Owner: CN=Test Certificate, OU=My Test Organization, O=Me, Inc., L=NY, ST=NY, C=US Issuer: CN=Test Certificate, OU=My Test Organization, O=Me, Inc., L=NY, ST=NY, C=US
Serial number: 39f3a2f3 Valid from: Sun Oct 22 22:31:15 EDT 2000 until: Sat Jan 20 21:31:15 EST 2001
Certificate fingerprints: MD5: 5E:B0:1C:D5:F6:2E:36:BF:F8:00:AA:4B:66:28:DE:DD
SHA1: 28:B7:83:D2:0E:95:1D:EE:C3:D7:A9:D4:D5:1E:0E:82:E0:E9:F3:8D
Trust this certificate? [no]: yes
Certificate was added to keystore
3.
At this point, we have two files. The keystore file contains the private key and a certificate that vouches for our identity; well use that as the servers keystore. The truststore file contains just the certificate; well use it
as the clients truststore.
14.1.2 JSSE Certificates
JSSE defines yet another certificate class, javax.security.cert.Certificate
. This class is not related either to the
java.security.cert.Certificate class that weve used in all our previous
examples or to the deprecated java.security.Certificate
interface. Since JSSE is designed to run on Personal Java implementations, for which the
java.security package is optional, it cannot rely on
classes from that package and must define its own certificate class. Suns reference implementation of JSSE, however, uses the
java.security.cert.Certificate class
internally, so it cannot run on versions of PersonalJava that do not supply the optional java.security
package. This does not prevent third parties from implementing JSSE independent of the java.security
package and providing those implementations with more limited PersonalJava packages. It does, however, limit the environments in which you can use Suns JSSE implementation.
The APIs of the java.security.cert.Certificate
and javax.security.cert.Certificate
classes are identical. However, there are no facilities to convert easily between the two classes; you must get the encoded bytes from the