Java Network Programming (3rd ed) [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Java Network Programming (3rd ed) [Electronic resources] - نسخه متنی

Harold, Elliotte Rusty

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








11.4 Creating Secure Server Sockets


fSecure client sockets are only half
of the equation. The other half is SSL-enabled server sockets. These
are instances of the
javax.net.SSLServerSocket class:

public abstract class SSLServerSocket extends ServerSocket

Like SSLSocket, all the constructors in this class
are protected. Like SSLSocket, instances of
SSLServerSocket are created by an abstract factory
class, javax.net.SSLServerSocketFactory:

public abstract class SSLServerSocketFactory 
extends ServerSocketFactory

Also like SSLSocketFactory, an instance of
SSLServerSocketFactory is returned by a static
SSLServerSocketFactory.getDefault( ) method:

public static ServerSocketFactory getDefault( )

And like SSLSocketFactory,
SSLServerSocketFactory has three overloaded
createServerSocket( ) methods that return
instances of SSLServerSocket and are easily
understood by analogy with the
java.net.ServerSocket constructors:

public abstract ServerSocket createServerSocket(int port) 
throws IOException
public abstract ServerSocket createServerSocket(int port,
int queueLength) throws IOException
public abstract ServerSocket createServerSocket(int port,
int queueLength, InetAddress interface) throws IOException

If that were all there was to creating secure server sockets, they
would be quite straightforward and simple to use. Unfortunately,
that's not all there is to it. The factory that
SSLServerSocketFactory.getDefault( ) returns
generally only supports server authentication. It does not support
encryption. To get encryption as well, server-side secure sockets
require more initialization and setup. Exactly how this setup is
performed is implementation-dependent. In Sun's
reference implementation, a
com.sun.net.ssl.SSLContext object is responsible
for creating fully configured and initialized secure server sockets.
The details vary from JSSE implementation to JSSE implementation, but
to create a secure server socket in the reference implementation, you
have to:

Generate public keys and certificates using
keytool.

Pay money to have your certificates authenticated by a trusted third
party such as Verisign.

Create an SSLContext for the algorithm
you'll use.

Create a TrustManagerFactory for the source of
certificate material you'll be using.

Create a KeyManagerFactory for the type of key
material you'll be using.

Create a KeyStore object for the key and
certificate database. (Sun's default is JKS.)

Fill the KeyStore object with keys and
certificates; for instance, by loading them from the filesystem using
the pass phrase they're encrypted with.

Initialize the KeyManagerFactory with the
KeyStore and its pass phrase.

Initialize the context with the necessary key managers from the
KeyManagerFactory, trust managers from the
TrustManagerFactory, and a source of randomness.
(The last two can be null if you're willing to
accept the defaults.)


Example 11-2 demonstrates this procedure with a
complete SecureOrderTaker for accepting orders and
printing them on System.out. Of course, in a real
application, you'd do something more interesting
with the orders.


Example 11-2. SecureOrderTaker


import java.net.*;
import java.io.*;
import java.util.*;
import java.security.*;
import javax.net.ssl.*;
import javax.net.*;
public class SecureOrderTaker {
public final static int DEFAULT_PORT = 7000;
public final static String algorithm = "SSL";
public static void main(String[] args) {
int port = DEFAULT_PORT;
if (args.length > 0) {
try {
port = Integer.parseInt(args[0]);
if (port < 0 || port >= 65536) {
System.out.println("Port must between 0 and 65535");
return;
}
}
catch (NumberFormatException ex) {}
}
try {
SSLContext context = SSLContext.getInstance(algorithm);
// The reference implementation only supports X.509 keys
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
// Sun's default kind of key store
KeyStore ks = KeyStore.getInstance("JKS");
// For security, every key store is encrypted with a
// pass phrase that must be provided before we can load
// it from disk. The pass phrase is stored as a char[] array
// so it can be wiped from memory quickly rather than
// waiting for a garbage collector. Of course using a string
// literal here completely defeats that purpose.
char[] password = "2andnotafnord".toCharArray( );
ks.load(new FileInputStream("jnp3e.keys"), password);
kmf.init(ks, password);
//
context.init(kmf.getKeyManagers( ), null, null);
SSLServerSocketFactory factory
= context.getServerSocketFactory( );
SSLServerSocket server
= (SSLServerSocket) factory.createServerSocket(port);
String[] supported = server.getSupportedCipherSuites( );
String[] anonCipherSuitesSupported = new String[supported.length];
int numAnonCipherSuitesSupported = 0;
for (int i = 0; i < supported.length; i++) {
if (supported[i].indexOf("_anon_") > 0) {
anonCipherSuitesSupported[numAnonCipherSuitesSupported++] =
supported[i];
}
}
String[] oldEnabled = server.getEnabledCipherSuites( );
String[] newEnabled = new String[oldEnabled.length
+ numAnonCipherSuitesSupported];
System.arraycopy(oldEnabled, 0, newEnabled, 0, oldEnabled.length);
System.arraycopy(anonCipherSuitesSupported, 0, newEnabled,
oldEnabled.length, numAnonCipherSuitesSupported);
server.setEnabledCipherSuites(newEnabled);
// Now all the set up is complete and we can focus
// on the actual communication.
try {
while (true) {
// This socket will be secure,
// but there's no indication of that in the code!
Socket theConnection = server.accept( );
InputStream in = theConnection.getInputStream( );
int c;
while ((c = in.read( )) != -1) {
System.out.write(c);
}
theConnection.close( );
} // end while
} // end try
catch (IOException ex) {
System.err.println(ex);
} // end catch
} // end try
catch (IOException ex) {
ex.printStackTrace( );
} // end catch
catch (KeyManagementException ex) {
ex.printStackTrace( );
} // end catch
catch (KeyStoreException ex) {
ex.printStackTrace( );
} // end catch
catch (NoSuchAlgorithmException ex) {
ex.printStackTrace( );
} // end catch
catch (java.security.cert.CertificateException ex) {
ex.printStackTrace( );
} // end catch
catch (UnrecoverableKeyException ex) {
ex.printStackTrace( );
} // end catch
} // end main
} // end server

This example loads the necessary keys and certificates from a file
named jnp3e.keys in the current working
directory protected with the password
"2andnotafnord". What this example
doesn't show you is how that file was created. It
was built with the keytool program
that's bundled with the JDK like this:

D:\JAVA>keytool -genkey -alias ourstore -keystore jnp3e.keys
Enter keystore password: 2andnotafnord
What is your first and last name?
[Unknown]: Elliotte
What is the name of your organizational unit?
[Unknown]: Me, Myself, and I
What is the name of your organization?
[Unknown]: Cafe au Lait
What is the name of your City or Locality?
[Unknown]: Brooklyn
What is the name of your State or Province?
[Unknown]: New York
What is the two-letter country code for this unit?
[Unknown]: NY
Is <CN=Elliotte, OU="Me, Myself, and I", O=Cafe au Lait, L=Brooklyn,
ST=New York, C=NY> correct?
[no]: y
Enter key password for <ourstore>
(RETURN if same as keystore password):

When this is finished, you'll have a file named
jnp3e.keys, which contains your public keys.
However, no one will believe that these are your public keys unless
you have them certified by a trusted third party such as Verisign
(http://www.verisign.com/).
Unfortunately, this certification costs money. The cheapest option is
$14.95 per year for a Class 1 Digital ID. Verisign hides the sign-up
form for this kind of ID deep within its web site, apparently to get
you to sign up for the much more expensive options that are
prominently featured on its home page. At the time of this writing,
the sign-up form is at samples (http://java.sun.com/products/jsse/). However,
this isn't good enough for real work.

For more information about exactly what's going on
and what the various options are, as well as other ways to create key
and certificate files, consult the online documentation for the
keytool utility that came with your JDK, the
Java Cryptography Architecture guide at http://java.sun.com/j2se/1.4.2/docs/guide/security/CryptoSpecl,
or the previously mentioned books Java
Cryptography, by Jonathan Knudsen, or Java
Security, by Scott Oaks (both from
O'Reilly).

Another approach is to use cipher suites that don't
require authentication. There are six of these in
Sun's JDK 1.4: SSL_DH_anon_WITH_RC4_128_MD5,
TLS_DH_anon_WITH_AES_128_CBC_SHA, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
SSL_DH_anon_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, and
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA.

These are not enabled by default because they're
vulnerable to a man-in-the-middle attack, but at least they allow you
to write simple programs without paying Verisign any money.


/ 164