Java security evolution and concepts, Part 5

J2SE 1.4 offers numerous improvements to Java security

1 2 3 4 Page 4
Page 4 of 4
    // get an instance of the default GSSManager
    GSSManager manager = GSSManager.getInstance();
    // Server name to connect 
    GSSName serverName = manager.createName(server, null);
    // Create the context
    GSSContext context = 
        manager.createContext(serverName,
                                                   krb5Oid,
                                                   null,
                                                   GSSContext.DEFAULT_LIFETIME);
    // Establish the context
    token = context.initSecContext(token, 0, token.length);
    // Send a token to the server if one was generated by
    // initSecContext
    if (token != null) {
        System.out.println("Will send token of size "
                                           + token.length + " from initSecContext.");
         outStream.writeInt(token.length);
         outStream.write(token);
         outStream.flush();
    }
    // More tokens ...
    if (context.getMutualAuthState())
        System.out.println("Mutual authentication took place!");
    // Encrypt message and send
    /*
     * The first MessageProp argument is 0 to request
     * the default Quality-of-Protection.
     * The second argument is true to request
     * privacy (encryption of the message).
     */
    MessageProp prop =  new MessageProp(0, true);
     /*
      * Encrypt the data and send it across. Integrity protection
      * is always applied, irrespective of encryption.
      */
     token = context.wrap(messageBytes, 0, messageBytes.length, 
        prop);
     System.out.println("Will send wrap token of size " 
         + token.length);
      outStream.writeInt(token.length);
      outStream.write(token);
      outStream.flush();

Next, here's the server's outline:

    // get an instance of the default GSSManager
    GSSManager manager = GSSManager.getInstance();
    // Server name to connect 
    GSSName serverName = manager.createName(server, null);
    // Create the context using default credentials
    GSSContext context = manager.createContext((GSSCredential)null);
    // Establish the context
    while (!context.isEstablished()) {
        token = new byte[inStream.readInt()];
        System.out.println("Will read input token of size "
            + token.length
            + " for processing by acceptSecContext");
         inStream.readFully(token);
                             
         token = context.acceptSecContext(token, 0, token.length);
    
         // Send a token to the peer if one was generated by
         // acceptSecContext
         if (token != null) {
             System.out.println("Will send token of size "
                 + token.length
                 + " from acceptSecContext.");
              outStream.writeInt(token.length);
              outStream.write(token);
              outStream.flush();
        }
    }
   System.out.print("Context Established! "); 
    
    if (context.getMutualAuthState())
        System.out.println("Mutual authentication took place!");
    // receive and decrypt message
    /*
     * Create a MessageProp which unwrap will use to return 
     * information such as the Quality-of-Protection that was 
     * applied to the wrapped token, whether or not it was 
     * encrypted, etc. Since the initial MessageProp values
     * are ignored, it doesn't matter what they are set to.
     */
     
    MessageProp prop = new MessageProp(0, false);
     /* 
      * Read the token. This uses the same token byte array 
      * as that used during context establishment.
      */
    token = new byte[inStream.readInt()];
        System.out.println("Will read token of size " 
             + token.length);
        inStream.readFully(token);
        byte[] bytes = context.unwrap(token, 0, token.length, prop);
        String str = new String(bytes);
        System.out.println("Received data \""
            + str + "\" of length " + str.length());
        System.out.println("Encryption applied: "
            + prop.getPrivacy());

JGSS API example programs

The JGSS installation includes sample programs. This section demonstrates how to run the client and server programs using JGSS for secure message exchange.

Before running the programs, you should have access to a Kerberos environment. However, installing and configuring Kerberos is not something for the fainthearted, so get some help if you need it.

Start kdc on the network. Start the server program. The server waits in a loop for connections. The following output illustrates the remaining steps through the program:

C:\rags\>java -Djava.security.krb5.realm=JILEBI.SUN.COM -Djava.security.krb5.kdc=jujub -Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.auth.login.config=bcsLogin.conf  SampleServer 9696
Waiting for incoming connection...
Got connection from client /24.128.136.197
Will read input token of size 490 for processing by acceptSecContext
Kerberos username [rags]: raghavan
Kerberos password for raghavan:
Will send token of size 106 from acceptSecContext.
Context Established! Client is raghavan@JILEBI.SUN.COM
Server is raghavan@JILEBI.SUN.COM
Mutual authentication took place!
Will read token of size 61
Received data "Hello There! " of length 13
Confidentiality applied: true
Will send MIC token of size 37
Closing connection with client /24.128.136.197
Waiting for incoming connection...

Now run the client program. The output below illustrates the steps through the program:

C:\rags>java -Djava.security.krb5.realm=JILEBI.SUN.COM -Djava.security.krb5.kdc=jujub -Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.auth.login.config=bcsLogin.conf  SampleClient raghavan anvil 9696
Connected to server anvil/24.128.136.197
Kerberos username [rags]: raghavan
Kerberos password for raghavan:
Will send token of size 490 from initSecContext.
Will read input token of size 106 for processing by initSecContext
Context Established!
Client is raghavan@JILEBI.SUN.COM
Server is raghavan
Mutual authentication took place!
Will send wrap token of size 61
Will read token of size 37
Verified received MIC for message.
Exiting...

The client and server programs establish a connection, mutually authenticate, and exchange a message with confidentiality assured.

JGSS and JSSE

You may wonder how the JGSS approach differs from the JSSE approach, which can also mutually authenticate the client and server and securely exchange messages. A cursory examination of the commands used to run the example programs show that the JGSS sample programs don't use the truststore. Instead, the mutual authentication proceeds with Kerberos. The other differences between the two are documented in the JGSS documentation and summarized in the table below.

Comparison of JGSS and JSSE. (Condensed from Sun Microsystems's "When to Use Java GSS-API vs. JSSE.")

AspectJGSSJSSE
Protocol requirementsKerberos version 5SSL/TLS
Kerberos single sign-on supportAvailable using a separate Kerberos installationNo support in SSL/TLS
Communications APIToken based -- dependent on applications such as TCP, UDP, etc.Socket based
Credential delegationPossible; suitable for intermediariesNot possible using the API
Selective encryptionPossible; suitable for this requirementUnsuitable for this requirement

Security is everyone's business

In this article, we looked primarily at the new features of J2SE 1.4 security. Java security has continually evolved by enhancing the flexibility of a secure environment. The movement of the optional packages into the core and the two new packages I discussed make it easier to incorporate a variety of security solutions in a portable fashion.

Throughout this series I've strived to offer simple examples to drive home the concepts. I leave it as an exercise to you to build more complex and realistic solutions. I hope those who wish to build more complex solutions will benefit from a knowledge of these simple examples and concepts.

Raghavan N. Srinivas is a Java technology evangelist at Sun Microsystems who specializes in Java and distributed systems. He is a proponent of Java technology and teaches graduate and undergraduate classes in the evening. Srinivas holds a master's degree in computer science from the Center of Advanced Computer Studies at the University of Southwestern Louisiana. He likes hiking, running, and traveling, but most of all loves to eat, especially spicy food.

Learn more about this topic

  • Java security resources from java.sun.com:
  • Security-related Java Specification Requests at the Java Community Process:
  • Other important Java security resources:
  • JavaWorld's Java security resources:
  • "Construct Secure Networked Applications with Certificates," Todd Sundsted (JavaWorld):
  • You'll find a wealth of IT-related articles from our sister publications at IDG.net

1 2 3 4 Page 4
Page 4 of 4