Using per-message services

After establishing a security context, two communicating peers can exchange secure messages over the established context.

Either peer can originate a secure message, regardless of whether it served as initiator or acceptor when establishing context. To make the message secure, IBM® JGSS computes a cryptographic message integrity code (MIC) over the message. Optionally, IBM JGSS can have the Kerberos V5 mechanism encrypt the message to help ensure privacy.

Sending messages

IBM JGSS provides two sets of methods for securing messages: wrap() and getMIC().

Using wrap()

The wrap method performs the following actions:
  • Computes an MIC
  • Encrypts the message (optional)
  • Returns a token

The calling application uses the MessageProp class in conjunction with GSSContext to specify whether to apply encryption to the message.

The returned token contains both the MIC and text of the message. The text of the message is either ciphertext (for an encrypted message) or the original plaintext (for messages that are not encrypted).

Using getMIC()

The getMIC method performs the following actions but cannot encrypt the message:
  • Computes an MIC
  • Returns a token

The returned token contains only the computed MIC and does not include the original message. So, in addition to transporting the MIC token to the peer, the peer must somehow be made aware of the original message so that it can verify the MIC.

Example: Using per-message services to send a message

The following example shows how one peer (foo) can wrap a message for delivery to another peer (superSecureServer):
     byte[] message = "Ready to roll!".getBytes();
     MessageProp mprop = new MessageProp(true); // foo wants the message encrypted
     byte[] wrappedMessage =
         fooContext.wrap(message, 0, message.length, mprop);
     send(wrappedMessage); // transfer the wrapped message to superSecureServer

     // This is how superSecureServer may obtain a MIC for delivery to foo:
     byte[] message = "You bet!".getBytes();
     MessageProp mprop = null;  // superSecureServer is content with
                                // the default quality of protection

     byte[] mic =
         serverAcceptorContext.getMIC(message, 0, message.length, mprop);
     send(mic);
     // send the MIC to foo. foo also needs the original message to verify the MIC

Receiving messages

The receiver of a wrapped message uses unwrap() to decode the message. The unwrap method performs the following actions:

If the sender encrypted the message, unwrap() decrypts the message before verifying the MIC and then returns the original plaintext message. The receiver of an MIC token uses verifyMIC() to verify the MIC over a given a message.

The peer applications use their own protocol to deliver JGSS context and message tokens to each other. Peer applications also need to define a protocol for determining whether the token is an MIC or a wrapped message. For example, part of such a protocol may be as simple (and rigid) as that used by Simple Authentication and Security Layer (SASL) applications. The SASL protocol specifies that the context acceptor is always the first peer to send a per-message (wrapped) token following context establishment.

For more information, see Simple Authentication and Security Layer (SASL).

Example: Using per-message services to receive a message

The following examples shows how a peer (superSecureServer) unwraps the wrapped token that it received from another peer (foo):
     MessageProp mprop = new MessageProp(false);

     byte[] plaintextFromFoo =
         serverAcceptorContext.unwrap(wrappedTokenFromFoo, 0,
                                      wrappedTokenFromFoo.length, mprop);

     // superSecureServer can now examine mprop to determine the message properties
     // (such as whether the message was encrypted) applied by foo.

     // foo verifies the MIC received from superSecureServer:

     MessageProp mprop = new MessageProp(false);
     fooContext.verifyMIC(micFromFoo, 0, micFromFoo.length, messageFromFoo, 0,
                          messageFromFoo.length, mprop);

     // foo can now examine mprop to determine the message properties applied by

     // superSecureServer. In particular, it can assert that the message was not

     // encrypted since getMIC should never encrypt a message.