Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

How Do I Transfer Data Securely?


Dr. Dobb's Journal February 1998: Java Q&A

Cliff, vice president of technology at Digital Focus, can be contacted at cliffbdf@ digitalfocus.com. To submit questions, check out the Java Developer FAQ web site at http://www.digitalfocus.com/faq/.


Protecting connections between client-server components against eavesdropping and other forms of compromise is vital. While secure connections are provided as an option with most commercial server software, what do you do if you are writing your own server? How can you provide this same functionality in your own code?

There are several options for implementing secure connections. Generic middleware, such as CORBA, often comes with Secure Socket Layer (SSL) connectivity. Java RMI can be used with SSL (although you must currently provide the SSL implementation yourself). But if you are writing your own middleware, you have to provide the security features using either basic security APIs, or by using a full-featured security package.

Characteristics of a Secure Connection

The security of a connection depends on the connection itself, the server, and the client. For each of these, you must consider the ability to prove identity, guarantee the data has not been altered, and ensure that the data has not been intercepted and successfully read by someone other than the intended recipient. Practically speaking, this means you must resort to encryption and authentication.

The SSL protocol developed by Netscape addresses all of these issues as a complete end-to-end solution, with the various components being optional. For example, Netscape servers use SSL to allow clients (users) to establish secure connections -- unreadable to anyone but the client and server -- but with no client authentication (that is, the server is not really sure the user is who he says he is). Netscape servers automatically use client authentication only if the user's program (Netscape Navigator, for instance) has a personal digital certificate installed.

How important is client authentication? For typical intranet applications, it is usually very important. In a call-center application, for example, operators may get paid based on the number of sales orders they complete. A salesperson's accounts and sales performance should be private, so one operator should not be able to log on as another and examine the other's performance. In a banking application, it is important that there be traceability as to who performs transactions on accounts. The robustness of the authentication is dependent on the application, and clearly an application that allows the transfer of money would require stronger authentication than one that merely displays account data.

What about server authentication? If the underlying network is relatively secure from manipulation of packets from the outside, then it can probably be assumed that a connection to an internal IP address is a good one, and once established, can be relied on as long as encryption is used. Server authentication is, therefore, not as important for an in-house application as it is for an open service that is made available on a public network (again, assuming that the private network is secure).

In some applications, establishing an authenticated connection is actually more important than providing a secure and encrypted connection. For example, the Secure Electronic Transaction (SET) standard guarantees that consumer transactions are traceable and auditable, and encrypts the credit card numbers of consumers all the way to the bank, but does not encrypt the purchases themselves. (So be careful what you buy!)

In most in-house security applications, encryption is a natural component. If you are going to go to the trouble of authenticating a connection, you might as well encrypt it while you are at it, because the act of authentication makes it possible to securely exchange an encryption key, from which point on you can encrypt data that is transmitted on the connection. How important data encryption actually is depends on the application. One reason not to encrypt, however, is that it will slow down the transfer of data. Another is that if you are communicating with offices overseas, the U.S. Department of Commerce restricts when you can "export" encryption, and you may have to fill out lengthy forms if you need encryption greater than a pre-approved "strength" (financial institutions can apply for exemptions).

Sometimes, you just want to securely transmit a password. For some applications, simply encrypting the password is sufficient. This is more difficult than it sounds, however. For example, there is the problem of distributing a secret encryption key to clients in such a way that the key can be updated from one location without having to physically send out diskettes with keys on them. Using the old key to encrypt the new key is not a good solution, because the very reason for distributing a new key is the possibility that the old key may have been compromised. A solution to this is to give the server a public and private key pair, and send the public key in the clear to all clients; clients can use this public key to encrypt passwords users enter, knowing that only the server's private key can unencrypt it. This does not prevent someone from monitoring the passage of your encrypted password on the network, and appropriating its encrypted value (then pretending to be you).

An alternative is to never unencrypt the password on the server -- simply compare the transmitted encrypted value with a stored encrypted value. This is what most password-based authentication systems do. The disadvantage is that if a password is forgotten, it can never be retrieved by anyone -- not even the system administrator. Note that this still does not prevent someone from intercepting the encrypted password and using that.

Passwords are a nuisance because we have so many of them. Another problem with passwords is that people share them in order to avoid the trouble of having to establish even more password accounts. Often, internal systems are given widely known passwords, so that no one has to remember them. This defeats the purpose of passwords. The real solution is to give each user a means of proving his identity, regardless of which system he is trying to gain access to; register that identity in a central location within your organization; and base all authentication on that identity. That is the topic of another column, however.

Using SSL from Java

Password-based authentication may be sufficient for some applications. If you will be sending company data over the Internet, however, you will probably want to consider using SSL, which provides a complete security solution with robust authentication and encryption. Phaos Technology (http:// www.phaos.com/) provides a full-featured implementation of SSL called "SSLava," which is completely written in Java. Since it is a pure-Java package, it can be used in an applet or any application. Listing One illustrates how you would use the Phaos toolkit to open an SSL connection to a server.

The first thing the code does is establish the session parameters. This includes the cipher suites, and a client certificate chain if client authentication is being used. Our example can use either: Diffie-Hellman key exchange, with DSS asymmetric key encryption of the symmetric key that will be used for actually encrypting the data, which will be encrypted using 40-bit DES; or RSA asymmetric keys for symmetric key exchange with triple-DES symmetric encryption. The latter assumes that we have obtained and installed the optional RSA module from Phaos to provide the RSA JSafe cipher suite from RSA Data Security. The full set of cipher suite options currently recognized by the Phaos product at the time of this writing is shown in Table 1.

Once you have defined the connection parameters, you can create the SSL socket connection. Socket construction encapsulates the entire set of handshaking between the client and server, for certificate exchange and key negotiation. When this is done, you have a secure connection. All that remains is to verify that the certificate of the Certificate Authority (CA) that signed the server's certificate is one that you recognize. You also need to specify the private key for your client certificate; the key is stored password-protected: in a real application this password would be obtained from the user interactively. (A private key is sent to you by a CA whenever you purchase a certificate.) You can get the CA certificate that the server sent you when it connected by calling the getServerCert().rootCA() methods on the connection. If the CA certificate is for a CA that you recognize, then you can have confidence in the connection, and you are ready to start communicating!

This connection could be to a Netscape server or to any server that supports SSL. Once the connection is established, the application can begin sending application commands; in the case of HTTP, for example, the GET and POST commands.

Implementing the server side is just as straightforward. The only real difference is that you must explicitly instruct the SSL layer to require a client-side certificate for all connections. You do this with the SSLParams.setRequestClientCert(boolean) method. Listing Two is an example of an SSL server program.

The 1.01 release of this package will work on JDK 1.02, 1.1, and future versions of the JDK. Also available is a 1.1-only release, 1.11, based on the JDK 1.1 socket model.

The Phaos SSL implementation is compatible with the JVM implementations of Netscape Communicator and IE 4.0. It comes with built-in support for Diffie-Hellman and DSS key generation and exchange, and DES and 3DES symmetric key encryption. In short, it provides a complete cryptographic toolkit for implementing SSL connectivity. You can also plug in an RSA cryptography module for supporting RSA keys and RC2/RC4 encryption: You may need this if your application will be interacting with other SSL connections. The tool also supports the SSL tunneling protocol for passing through firewalls.

In the future, Phaos plans to modify its cryptographic implementation to use the JCE architecture, but this should be transparent to programs, since this is completely encapsulated by the SSL protocol layer. Phaos also plans to add support for SSL v.2 (an earlier version of SSL used by Netscape 2.0 and earlier Netscape servers), Transport Layer Security (the emerging public standard, which is intended to replace SSL), and smartcards (in which a private key or certificate is embedded in an active card device, rather than stored on a user's machine).

Certificate Management

Establishing the connection is only part of the job. In Listings One and Two, a digital certificate is read from a file and provided to the SSL layer. In the server code snippet, this is the server's certificate. If the application requires client authentication, the client application will have to know where these certificates reside on the client machine so that it can retrieve them and provide them to SSL. The Netscape Communicator client program performs its own certificate management, and maintains a certificate database for each user. This database consists of the user's personal certificates (if any) and all of the server certificates that have been transferred via SSL to the browser and accepted by the user. It also contains a set of trusted CA certificates. When a server certificate finds its way to the browser, it must be signed by a CA certificate that is installed in the user's certificate database -- that's how the validity of a server certificate can be proved.

If you write your own SSL application, you will have to manage client (and possibly server) certificates. Most SSL vendors (including Phaos) provide a certificate-management toolkit for reading and parsing certificates. You still have the task, however, of designing a system for storing and handling these certificates. The java.security.Identity mechanism is provided by the JDK to manage keys and certificates; however, it will not handle X.509 v3 certificates (the kind used by SSL) until JDK 1.2 is available. In the meantime, you can simply put your client certificates in a directory known to your application.

Conclusion

Don't underestimate the importance of creating secure and authenticated connections between applications. The Java Virtual Machine and security architecture make it possible to build secure computing environments within a single machine. Secure connections complete the picture by allowing that security to extend to the links between machines. Open standards like Java, SSL, and distributed protocols such as CORBA and RMI provide the tools to create an extremely secure, reliable, and maintainable infrastructure for corporate computing. This capability does not have to be limited to commercial server products either. Toolkits such as SSLava allow you to add your own SSL connectivity to any application.

DDJ

Listing One

static final int MyServerPortNo = 1000;
SSLParams params = new SSLParams();
short cs[] = { SSLParams.SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
                 SSLParams.SSL_RSA_WITH_3DES_EDE_CBC_SHA };
	// these are the cipher suites that our client will accept
	// when negotiating with an SSL server. Note that we are saying
	// we have RSA support.

params.setClientCipherSuites(cs);

// Do the following five lines if client authentication is required
// by the server:
SSLCertificate cert = new SSLCertificate();
cert.certificateList = new Vector();
cert.certificateList.addElement(new X509(new File("client-cert.der")));
cert.certificateList.addElement(new X509(new File("ca-cert.der")));
cert.privateKey = new RSAPrivateKeyPKCS8("password",
		new File("encrypted-client-key.der"));
params.setClientCert(cert);

SSLSocket s = new SSLSocket("myserverhost.com", MyServerPortNo, params);
// Note: the above checks the validity of all certificates up to the
// root certificate.

// Get the certificate chain presented by the server
SSLCertificate schain = s.getServerCert();

if (schain != null)	// if the server cert chain is presented
{
	// Check if the root CA of the server cert chain is valid
	if (! schain.rootCAvalid())
		throw new Exception("Invaild CA certificate");
		// (usually, abort when this exception occurs)
	

	// Here we get information about the root certificate; in an
	// actual application, you would likely make this information
	// available only upon user request.

	// Get the actual root certificate from the server certificate chain
	X509 ca = schain.rootCA();
	System.out.println("CA=" + ca.getIssuer().toString());

	// Get the CA's public key
	System.out.println("CA public key=" +
		ca.getPublicKey().toString());
}

PrintWriter os = new PrintWriter(s.getOutputStream());
BufferedReader is = new BufferedReader(
	new InputStreamReader(s.getInputStream()));
	  
// ...start reading and writing on connection...

Back to Article

Listing Two

SSLParams params = new SSLParams();

// Construct a server certificate chain
SSLCertificate cert = new SSLCertificate();
cert.certificateList = new Vector();
cert.certificateList.addElement(new X509(new File("server-cert.der")));
cert.certificateList.addElement(new X509(new File("ca-cert.der")));
cert.privateKey = new RSAPrivateKeyPKCS8("password",
		new File("encrypted-server-key.der"));
params.setServerCert(cert);

// Turn on client authentication - the client will have to present
// a client certificate (this is optional)
params.setRequestClientCert(true);

// Create a server socket to listen for connection requests
SSLServerSocket ss = new SSLServerSocket(MyServerPortNo, params);

// Start listening (this and all the following code would normally 
// be in a loop that allocates a thread to service each incoming
// connection)
SSLSocket s = (SSLSocket)ss.accept();

if (s.getClientCert() == null)
	throw new Exception("Client has no certificate!");

if (! s.getClientCert().rootCAValid())
	throw new Exception("Invalid CA certificate!");

PrintWriter os = new PrintWriter(s.getOutputStream());
BufferedReader is = new BufferedReader(
	new InputStreamReader(s.getInputStream()));
	  
//...start reading and writing on connection...

Back to Article

DDJ


Copyright © 1998, Dr. Dobb's Journal


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.