Skip to main content

Lock down J2ME applications with Kerberos, Part 1: Introducing Kerberos data formats

Understand how Kerberos ensures wireless security

Faheem Khan (fkhan872@yahoo.com), Freelance Consultant
Faheem Khan is an independent software consultant specializing in enterprise application integration (EAI) and B2B solutions. Readers can reach Faheem at fkhan872@yahoo.com.

Summary:  Users need assurance that the wireless applications they use won't compromise their sensitive information. One way to do that is to use industry-standard protocols like Kerberos to provide security. In this series, Faheem Khan will build a sample J2ME MIDlet that uses Kerberos to protect financial data. In this first article of the series, he lays the foundation by explaining the Kerberos data formats that will provide the backbone for his application's security.

Date:  28 Oct 2003
Level:  Intermediate
Comments:  

Many users are reluctant to use applications that send sensitive data over wireless connections because they don't trust wireless security. But the same protocols that make secure e-commerce over traditional wired networks possible can also help make wireless transactions safe. In this three-part article series, I'll demonstrate secure messaging between J2ME clients and server-side Java applications using the Kerberos protocol (see Resources for a link). I will develop a mobile banking MIDlet application that can send and receive payments securely over the Internet. The MIDlet application will use a J2ME-based Kerberos client to perform the actual secure messaging. In this article, I'll begin by explaining the usage model of a mobile banking application. I will then explain the sequence of Kerberos message exchanges that results in the establishment of a secure context for subsequent secure messaging between a J2ME client and a server-side Java application. This discussion will be followed by a description of the data formats used in Kerberos messaging. The last section of this article will briefly introduce the architecture of the Kerberos client, which will eventually author and process Kerberos messages and data formats.

A secure MIDlet for mobile banking

I'll start the discussion by considering a use-case scenario in which two mobile phone users, Alice and Bob, have a bank account with an e-bank.

If Alice wants to make a payment to Bob, she provides Bob's cell phone number (or perhaps his bank account number) to the MIDlet application and asks the MIDlet to make a payment to him. The MIDlet securely contacts the e-bank and requests that the e-bank make the payment to Bob. The e-bank completes the transaction and sends an acknowledgement back to Alice. Bob also has the MIDlet installed in his cell phone, which he can use to see if the payment from Alice has reached his account. The MIDlet communicates securely with the e-bank to verify payment status.

The MIDlet that I'll design and implement in this series of articles handles all application-specific messaging with the e-bank. Naturally, the MIDlet must ensure that the communication is secure. The following features constitute the security requirements for the MIDlet:

  • The e-bank should be able to confirm the identity of users making requests for payments and account status updates. This security requirement is commonly known as authentication, where the server wants to authenticate the identity of a requesting client.
  • Users, such as Alice and Bob, should be able to ensure that they are actually talking to their e-bank and not some malicious hacker. This is also an authentication scenario in which the client wants to authenticate the server. A situation in which a client and server authenticate each other is called mutual authentication.
  • All communication should be encrypted to maintain message confidentiality. Even if a hacker is able to fetch bytes of the message traveling over the network, he will not be able to understand the meaning of those encrypted data bytes.
  • Both communicating parties (the users and the e-bank) should be able to validate the integrity of an incoming message. If a malicious hacker changes a message while it is in transit, the receiving party should be able to detect this change.

I'm going to use the Kerberos protocol to fulfill these security requirements. (See Resources for links to more information on Kerberos.) I'll wrap all Kerberos-related functionality in a small-footprint client-side Kerberos implementation suitable for J2ME devices. Our mobile banking MIDlet will only have to take care of application-specific messaging features, while the Kerberos client will handle all security issues.

This technique has an advantage for readers. The Kerberos client wraps security features (authentication, confidentiality, and message integrity). Therefore, if you want to develop your own MIDlet for some purpose other than making and receiving payments, you can add security features to it by using the Kerberos client outlined here.

I'll spend most of this article discussing how Kerberos works with the application and describing the various messages exchanged between the client and server in order to create secure communications. I'll outline the client-side application itself in detail in subsequent installments of this series.


Exchange of Kerberos messages

In this section, I'll describe the exchange of Kerberos messages between three actors:

  • A J2ME-enabled wireless device
  • A wireless device user
  • An e-bank

Figure 1. An exchange of Kerberos messages to establish a secure communication context
An exchange of Kerberos messages to establish a secure communication context

Figure 1 shows a high-level view of an exchange of messages occurring between these three actors. In this section, I'll discuss this view and explain the net outcome of the exchange of messages shown in the figure. The next section explains the fine details (that is, the structure and format) of each of the messages.

Notice in Figure 1 that the J2ME-enabled wireless device contains two actors: the MIDlet and the Kerberos client. Similarly, the e-bank's system also contains two actors: a business logic server and a Kerberos Distribution Center (KDC).

The business logic server is a server-side Java application that implements the business logic of the e-bank. The KDC is a Kerberos server that manages and distributes Kerberos tickets. The KDC is further composed of two servers: an authentication server (AS) and a ticket granting server (TGS). Both the AS and the TGS receive client requests and issue Kerberos tickets in response to those requests. When the AS receives a request for a ticket from a client, it issues an initial ticket. The client then presents the initial ticket to the TGS. The TGS will issue a service ticket against the initial ticket.

The main purpose of getting an initial ticket is to use it at a later time to get one or more service tickets against the initial ticket. That's why an initial ticket is also known as a ticket granting ticket (TGT).

Note that a service ticket is meant for secure communication between the client and a particular server. On the other hand, a TGT is not intended for any particular server. Therefore, a TGT is logically equivalent to an open-ended connection, whose one end is the client and other end is unknown. When a service ticket is issued against a TGT, the other end is also decided. The same TGT can be used to fetch any number of service tickets.

The steps of the exchange of messages outlined below demystifies how and why the MIDlet fetches and uses Kerberos tickets. Each number in Figure 1 corresponds to a step in the following discussion.

  1. The cell phone user provides his or her username and password (a shared secret that only the user and the e-bank know) to the MIDlet application. The password is only used for processing inside the J2ME application; it never travels across any network. Only the username is sent across the network.
  2. The MIDlet hands the username and password to the Kerberos client. It is the Kerberos client's job to establish a context for secure commutation with the e-bank.
  3. The Kerberos client authors a request for the AS to issue a TGT. A single TGT represents a secure session. A client can establish a number of sub-sessions within a single secure session. A request for a TGT includes the username of the requesting client. It does not include the password (the shared secret).
  4. The Kerberos client sends the request to the AS.
  5. When the AS receives the TGT request, it extracts the username from the request and fetches the corresponding password (the shared secret) from its internal database. The AS then authors a TGT and wraps the TGT in a reply message. The TGT contains a plain text portion and a cipher text (encrypted) portion. In order to encrypt the cipher text portion of the TGT, the AS uses a cryptographic key derived from the user's password. Therefore, only a user who knows the password can decrypt the encrypted portion. The encrypted portion of the TGT also contains a cryptographic key, known as a session key.
  6. The AS sends the reply message (along with the TGT) to the requesting Kerberos client.
  7. Upon receipt of the reply from the AS, the Kerberos client extracts the TGT from the reply and decrypts the encrypted portion of the TGT. The Kerberos client then authors a request for a service ticket. The request will wrap the TGT and an encrypted structure known as an authenticator. The client encrypts the authenticator using the session key that it extracted from the TGT. The authenticator certifies the client's knowledge of the session key. The service ticket request also specifies the name of the e-bank's business logic server.
  8. The client sends the service ticket request to the TGS (which is part of the e-bank's KDC).
  9. Upon receipt of the service ticket request, the TGS extracts the name of the server for whom the client is requesting the service ticket. It then authors a service ticket. A service ticket is not very different from a TGT. Just like a TGT, a service ticket contains a plain text portion and a cipher text (encrypted) portion. The TGS encrypts the cipher text portion of the service ticket with the server's secret key (a key derived from the server's shared secret), so that only the server can decrypt the cipher text portion of the service ticket. The TGS also includes a new cryptographic key in the cipher text portion of the service ticket. This key is called a sub-session key. Notice that now there are now two keys: a session key and a sub-session key.
  10. After authoring a service ticket, the TGS wraps the service ticket in a response message. The response message also includes a cipher text portion, which is encrypted using the session key. The cipher text portion of the response message includes the sub-session key.
  11. The TGS sends the response message to the client.
  12. Upon receipt of the TGS response, the client decrypts its cipher text portion using the session key, thus extracting the sub-session key. The client also extracts the service ticket.
  13. The client then authors a message for the e-bank's business logic server and wraps the service ticket in the message. The message is a request to the server for establishing a new secure session with the client.
  14. The client sends the message to the e-bank's business logic server.
  15. The e-bank's business logic server extracts the service ticket from the request, decrypts its cipher text part, and fetches the sub-session key. This key is now known at both the client and the server.
  16. The e-bank's server sends a positive acknowledgement to the client.

The client and e-bank's server can now securely communicate with each other using the sub-session key.


Kerberos messages

So, how does all the encryption work? For most of the remainder of this article, I'll explore in detail the structure of the Kerberos messages exchanged in steps 3 through 16 in Figure 1.

The request for a TGT

Figure 2 is a diagrammatic representation of the TGT request message discussed in step 3 of Figure 1.


Figure 2. The structure of a TGT request message
The structure of a TGT request message

The Kerberos protocol defines titles for all data structures and messages used in Kerberos messaging. Notice in Figure 2 that the title of the message is AS-REQ -- that is, it is a request to the AS.

Figure 2 shows a box-inside-a-box structure. Each box represents a data field. Some of the fields consist of various fields in turn, thus forming a nested hierarchy.

The outer box, labeled AS-REQ, consists of a smaller box labeled KDC-REQ. The KDC-REQ box consists of four fields:

  • pvno: This data field represents the Kerberos protocol version number. The discussion in this series of articles centers on Kerberos version 5, which is quite stable and is, for the moment, the most recent.
  • msg-type: You can identify different Kerberos messages through their message type numbers. The type number of a TGS request message is 10.
  • padata: This is an optional field and will be left out of most of the TGT request messages. The purpose of this field is to include authentication information. I'll describe the structure of padata fields while describing the request for a service ticket later in this section.
  • The fourth field is labeled req-body; it is the body of the TGT request. It is, in turn, further divided into several more fields:
    • kdc-options: This field represents KDC options. Kerberos defines a list of several options that a client might want to request. For example, a client might need a forwardable ticket (a ticket that can be forwarded to a different KDC server). Similarly, a client might also request a renewable ticket (one that can be renewed after expiry). Later in this series of articles, I'll discuss some of the available options, especially those options that are related to our mobile banking application.
    • cname: The client's username.
    • realm: The KDC realm. Notice that every organization that uses Kerberos can establish its own realm. A realm is like a trusted domain; like our e-bank for example. A realm might or might not cross the boundaries of an enterprise. This means that a realm might or might not have to talk to users that belong to a different enterprise. In the mobile banking application, I will keep things simple and assume that all users (like Alice and Bob) are registered with the e-bank's own enterprise.
    • sname: A name identifying the server to which the client will present the ticket being requested. In the case of a TGT request, the sname field specifies the name of the TGS (because the client will eventually present the TGT to the TGS). On the other hand, in the case of the service ticket request (you'll see one of these later in this section), the sname field will specify the name of the e-bank's server (because the client eventually intends to present the service ticket to the e-bank's business logic server).
    • from: This is an optional field to indicate that the client needs a postdated ticket, whose validity will start at some point in the future. I don't need this feature in the mobile banking application.
    • till: This field indicates the time at which the TGT expires. The client specifies the time at which the TGT will expire. All Kerberos time fields follow the YearMonthDateHourMinSecZ format. For example, 3:30 am on August 14, 1947, would be represented as 19470814033000Z.
    • rtime: This field specifies the time after which the ticket will not be renewable. It is an optional field and will be used only when the client has selected the renewable option in the kdc-options field.
    • nonce: This is a randomly generated integer. Although this integer has no meaning in and of itself, it helps in detecting replay attacks.
    • etype: This field specifies the encryption algorithm that the client wants to use. Kerberos defines various integer values for popular encryption algorithms. The client will use the integer values of its choice.
    • addresses: This is an optional field that contains a list of addresses from which the ticket will be valid. The client can specify here the network addresses from which it intends to use the ticket being requested.
    • enc-authorization-data: This is an optional field that wraps authorization data, based on which server can enforce its authorization policies. I am not going to demonstrate the use of this feature in the mobile banking application.
    • additional-tickets: This is an optional field that allows Kerberos clients to request a secure session based on multiple tickets already obtained by the client. I am not going to use this feature in the mobile banking application.

Defining data structures with ASN.1

Kerberos uses Abstract Syntax Notation One (ASN.1) to define the various data structures and byte formats used in Kerberos communication. ASN.1 is an ITU-T (International Telecommunication Union-Telecommunication standardization sector) standard. It consists of various documents with reference numbers ranging from X.680 to X.699 (see Resources for a link).

ASN.1 syntax and encoding details are not the focus of this article. However, I need to discuss some ASN.1 concepts in order to explain Kerberos structures and byte formats. I will cover only those ASN.1 concepts that are needed to explain Kerberos message formats.

Byte encoding of Kerberos messages Before discussing the rest of the Kerberos messages, I'll first describe how to encode the TGT request message in Figure 2 as a sequence of byte values.

Listing 1 is the ASN.1 class definition of the TGT request message in Figure 2. (See the sidebar for more on ASN.1.) Table 2, which you'll encounter shortly, shows the byte-by-byte format that encodes the TGT request message. In order to understand the byte encoding of the TGT request message, you have to relate Figure 2, Listing 1, and Table 2 with each other.

Notice that the main structure in Listing 1 is labeled AS-REQ. The same AS-REQ label appears on the outer box in Figure 2.

Now look what follows AS-REQ in Listing 1. The two colons and the 'equals' sign (::=) after AS-REQ mean that this line defines the AS-REQ structure. A string, APPLICATION 10, follows in square brackets. APPLICATION 10 means that the AS-REQ structure is identified as number 10 among the different structures of this APPLICATION. We can say that the number 10 is an application-level tag number. This number is unique throughout the application -- in other words, no other Kerberos structure will bear this number.

Now notice that a KDC-REQ string follows the [APPLICATION 10] string. This means that format of the AS-REQ structure follows the definition of another structure named KDC-REQ. This is a reusability mechanism in ASN.1. The KDC-REQ structure is used in two different places. Therefore, Kerberos defines KDC-REQ once and uses it twice.

Summarizing, AS-REQ ::= [APPLICATION 10] KDC-REQ means that AS-REQ is identified as number 10 among the different structures of this application and follows the definition of another structure named KDC-REQ.


Listing 1. The ASN.1 class definition of the TGT request message
AS-REQ ::=         [APPLICATION 10] KDC-REQ
KDC-REQ ::=        SEQUENCE {
           pvno[1]               INTEGER,
           msg-type[2]           INTEGER,
           padata[3]             SEQUENCE OF PA-DATA OPTIONAL,
           req-body[4]           KDC-REQ-BODY
}

PA-DATA ::=        SEQUENCE {
           padata-type[1]        INTEGER,
           padata-value[2]       OCTET STRING,
                         -- might be encoded AP-REQ
}

KDC-REQ-BODY ::=   SEQUENCE {
            kdc-options[0]       KDCOptions,
            cname[1]             PrincipalName OPTIONAL,
                         -- Used only in AS-REQ
            realm[2]             Realm, -- Server's realm
                         -- Also client's in AS-REQ
            sname[3]             PrincipalName OPTIONAL,
            from[4]              KerberosTime OPTIONAL,
            till[5]              KerberosTime,
            rtime[6]             KerberosTime OPTIONAL,
            nonce[7]             INTEGER,
            etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
                         -- in preference order
            addresses[9]         HostAddresses OPTIONAL,
            enc-authorization-data[10]   EncryptedData OPTIONAL,
                         -- Encrypted AuthorizationData encoding
            additional-tickets[11]       SEQUENCE OF Ticket OPTIONAL
}

EncryptedData ::=   SEQUENCE {
            etype[0]     INTEGER, -- EncryptionType
            kvno[1]      INTEGER OPTIONAL,
            cipher[2]    OCTET STRING -- ciphertext
}

KDCOptions ::=   BIT STRING {
                    reserved(0),
                    forwardable(1),
                    forwarded(2),
                    proxiable(3),
                    proxy(4),
                    allow-postdate(5),
                    postdated(6),
                    unused7(7),
                    renewable(8),
                    unused9(9),
                    unused10(10),
                    unused11(11),
                    renewable-ok(27),
                    enc-tkt-in-skey(28),
                    renew(30),
                    validate(31)
}

PrincipalName ::=   SEQUENCE {
              name-type[0]     INTEGER,
              name-string[1]   SEQUENCE OF GeneralString
}

KerberosTime ::=   GeneralizedTime
            -- Specifying UTC time zone (Z)


HostAddresses ::=   SEQUENCE OF SEQUENCE {
                    addr-type[0]             INTEGER,
                    address[1]               OCTET STRING
}

Now let's see what a KDC-REQ structure is.

The KDC-REQ ::= SEQUENCE line in Listing 1 means that the KDC-REQ structure is a sequence of different data structures. The set of curly brackets that follow the SEQUENCE keyword describe the data structures that collectively form the KDC-REQ structure.

There are four lines of code within the curly brackets. The first line (pvno[1] INTEGER) defines the first element of the KDC-REQ structure, which is the pvno field in Figure 2.

The second line (msg-type[2] INTEGER) corresponds to the msg-type field in Figure 2. Notice that both the pvno and the msg-type fields are of type INTEGER, which means that they are constructed using the INTEGER data type.

Also notice the numbers in square brackets after pvno and msg-type in Listing 1 (pvno[1] and msg-type[2]). These are context-specific tag numbers, as opposed to the application-level tag numbers that you saw earlier in the AS-REQ ::= [APPLICATION 10] KDC-REQ line.

What's the difference between application-level and context-specific tag numbers? Application-level tag numbers are unique and valid throughout an application. For example, the number 10 will mean the AS-REQ structure throughout the Kerberos application. Context-specific tag numbers are meaningful only within the context in which they are defined. For example, when you are looking inside the KDC-REQ structure, the context-specific tag number 1 will mean pvno. But when you are looking inside some other structure, the same context-specific tag number 1 will represent some other field.

Later, I'll explain the use of these application-level and context-specific tag numbers while discussing the encoding of Listing 1 as the byte sequence in Table 2.

Now look at the third (padata[3] SEQUENCE OF PA-DATA) and fourth (req-body[4] KDC-REQ-BODY) lines in the KDC-REQ structure in Listing 1. The third line defines the padata field in Figure 2, which is a SEQUENCE of PA-DATA structures. The fourth line represents the req-body box in Figure 2.

The padata and req-body fields are, in turn, Kerberos structures composed of different fields. For example, the data type of req-body is KDC-REQ-BODY, which is itself a Kerberos structure with several fields (kdc-options, cname, realm, sname, till, nonce, and etype, as already discussed).

Recall that the pvno field was constructed using just one INTEGER. On the other hand, the req-body field has data type KDC-REQ-BODY, which is itself a structure that is constructed from several fields.

Notice also that INTEGER is an example of a primitive ASN.1 data type, while KDC-REQ-BODY is a derived data type constructed from other fields.

ASN.1 defines some data types for ready use by applications, called universal data types. Most of the universal data types are primitive, while only a few are constructed. ASN.1 defines tag numbers for universal data types, as shown in Table 1.

Table 1. Some universal data types and tag numbers

Universal data typeUniversal tag numberConstructed or primitive?
BOOLEAN1Primitive
INTEGER2Primitive
BIT STRING3Primitive
OCTET STRING4Primitive
SEQUENCE16Constructed
GeneralizedTime24Primitive
GeneralString27Primitive

Table 1 shows that the universal tag number for the INTEGER data type is 2 and that an INTEGER data type is primitive. SEQUENCE is the only universal tag in Table 1 that is constructed. This is because the SEQUENCE data type is universally defined and a SEQUENCE is always constructed using other fields.

Tag numbers for universal data types are not mentioned in ASN.1 definitions because these tag numbers are universally defined and understood. However, you need universal tag numbers when you try to encode a Kerberos structure as a sequence of bytes. You'll see that shortly.

Now, let me explain how the AS-REQ message of Figure 2 and Listing 1 is encoded as a byte sequence. In order to illustrate the encoding process, I've provided Table 2, which shows the actual sequence of bytes in a TGT request (an AS-REQ structure) that a client sends to a KDC server to request for a TGT. The byte sequence shown in Table 2 is the final result of the AS-REQ encoding process that we are about to study.

Because of its length, I've provided Table 2 in a separate file. You will want to keep it open in a separate browser window for reference while you read the following discussion.

Look at the first byte in Table 2 (01101010). This first byte of the message represents the start of the AS-REQ structure of Listing 1 (the outer box in Figure 2). Bits 8 and 7 (01) mean that this is an application-level tag. Bit 6 (1) means this is a constructed structure. Bits 5 through 1 (01010) represent AS-REQ's tag number (recall from my earlier discussion that the application-level tag number of AS-REQ structure is 10, the binary equivalent of which is 01010).

You can say that a tag byte is divided into three portions:

  • Bits 8 and 7 specify the type or class of the tag. For an application-level tag, bits 8 and 7 should be 01; for a context-specific tag, they should be 10; and for a universal tag, they are 00.
  • Bit 6 specifies whether the tag is primitive (0) or constructed (1).
  • Bits 5 to 1 encode the tag number.

You might wonder why there are just five bits available for tag numbers because this limits the number of tags you can have. ASN.1 defines a complete mechanism for encoding tag numbers, no matter how large a tag number is. However, Kerberos does not define any tag number that you cannot accommodate within five bits. Therefore, in order to keep the focus on Kerberos, I will not discuss how to handle large tag numbers here.

Now, look at the second byte in Table 2 (10000001). Just after the tag byte, you have one or more length bytes. The length bytes specify the total number of bytes that form the complete tag.

There are two ways of defining a length byte. The first is a single-byte length notation, and the second is a multi-byte length notation. In single-byte length notation, you will leave bit 8 of the first length byte as 0 and use the rest of the bits to specify the number of length bytes. For example, if you want to say that there are 65 bytes in this structure, you can encode this length value as 01000001 (bit 8 is set to 0 and bits 7 to 1 -- 1000001 -- mean 65). In this method, there is always just one length byte, and the next byte marks the start of the contents of the structure. You can encode a maximum value of 127 using this method.

In multi-byte notation, you set bit 8 of the first length byte as 1 and use bits 7 to 1 to specify the number of length bytes that will follow. For example, if you want to encode a value of 210, your first length byte will be 10000001 (bit 8 set to 1 and bits 7 to 1, 0000001 specifying that there is one more length byte) followed by another byte with value 11010010 (meaning 210 in decimal).

Look at byte numbers 2 and 3 in Table 2, which are 10000001 and 11010010, respectively. This means I have used multi-byte length notation to specify the length of the AS-REQ structure, which is 210.

Notice that there are a total of 213 bytes in Table 2, of which 210 occur after byte number 3. All 210 bytes that occur after byte number 3 belong to the AS-REQ structure. Therefore, byte number 4 and all bytes thereafter form the contents of the AS-REQ structure.

Notice in Listing 1 that the AS-REQ structure follows the definition of the KDC-REQ structure, which is a SEQUENCE. Recall from Table 1 that a SEQUENCE is a universal tag, is a constructed data type, and has a tag number 16. That's why byte number 4 in Table 2 has a value of 00110000. Bits 8 and 7 (00) specify that this is a universal tag. Bit 6 (1) means that this structure is constructed. Bits 5 to 1 specify the tag number, which is 16 (binary 10000) for a SEQUENCE.

Bytes 5 and 6 identify the number of bytes in the KDC-REQ structure. Byte 5 (10000001) specifies that there is one length byte. Byte 6 (11001111) specifies the actual length (207) of the KDC-REQ sequence. I have already explained how the length bytes work.

The first field of the KDC-REQ sequence in Listing 1 is pvno, which is a context-specific, constructed field with tag number 1. Byte 7 of Table 2 (10100001) represents this field. Bits 8 and 7 (10) mean this is a context-specific tag. Bit 6 (1) means that this is a constructed field, and bits 5 to 1 (00001) specify the tag number of the pvno field.

Byte 8 (00000011) specifies the length of the pvno field. Bit 8 of this length byte is 0, which means that I am using single-byte length notation. Bits 7 to 1 (0000011) specify the length, which is 3. Here, notice that whenever the length of the structure is less than 127, I use the single-byte length notation, as already explained above.

The contents of the pvno field start with byte number 9 in Table 2. The pvno field is constructed using an INTEGER primitive data type, so I should expect the contents of pvno to be an integer value.

Byte 9 (00000010) represents the INTEGER tag. Bits 8 and 7 (00) identify this as a universal tag, bit 6 (0) says that it is primitive, and bits 5 to 1 (00010) mean that the tag number is 2 (see Table 1).

Byte 10 (00000001) provides the length of this INTEGER data type in single-byte length notation. The INTEGER value consists of just one byte, which is the next one (byte number 11).

You'll have noticed by now that the byte encoding process is following a clear pattern. I start with a tag value corresponding to a field in Listing 1. The length bytes follow the tag value, and then the contents of the tag follow the length bytes. I keep following a nested hierarchy of constructed structures until I reach a primitive data type.

You can follow Table 2 according to this pattern. The description column in Table 2 will help you understand the function of each byte. I won't be providing a byte-by-byte breakdown of the other messages I'll discuss in this article, but this one should give you an idea of how they work.

The response that wraps the TGT

Figure 3 is a graphical representation of the response message from the AS that wraps the TGT. Figure 3 follows the same box-within-a-box structure that I showed in Figure 2.


Figure 3. The structure of a TGT response from the AS
The structure of a TGT response from AS

The main (outer) box in Figure 3 is labeled AS-REP; it contains a smaller box labeled KDC-REP. KDC-REP is a sequence of several fields:

  • pvno: I explained this field while discussing Figure 2.
  • msg-type: The type of the message. It is an integer whose value should be 11 for a TGT response message.
  • padata: I went over this field while discussing Figure 2. This is an optional field and will be left out of most of the TGT response messages.
  • crealm and cname: These fields were explained while discussing Figure 2.
  • ticket: The actual TGT. I'll discuss the format of the Kerberos tickets themselves in a subsequent section of this article.
  • enc-part: This is a wrapper for encrypted data. All encrypted portions in Kerberos messages consist of three fields:
    • etype: An identifier to specify the encryption algorithm used to perform cryptographic encryption.
    • kvno: The version of the cryptographic key used for encryption. The AS uses the client's secret key to perform encryption. This field specifies the version of the key that was used to perform encryption.
    • cipher: A series of bytes. This is the actual encrypted data. Once the data has been decrypted, I have another structure, illustrated in Figure 4.

Figure 4. The structure of the encrypted portion of a TGT response message
The structure of the encrypted portion of a TGT response message

Figure 4 shows the structure that results from decrypting the encrypted part of the TGT response message. It contains the following fields:

  • key: This is the session key. Subsequent communication in the current session will use this key instead of the secret key.
  • last-req: This field specifies the time of the last ticket request from the client. This field helps in keeping the client informed about the requests being received from the client.
  • nonce: I explained this field when discussing Figure 2. The AS will include a copy of the same random number that it received in the request. This helps in detecting replay attacks. If a hacker fetches a TGT response and wants to replay it again and again, the client can match the nonce field of the response with its request to detect replays.
  • key-expiration: This is an optional field that specifies the time at which the client's secret key expires.
  • flags: This field corresponds to the kdc-options field of the TGT request of Figure 2. These flags represent the various optional features that a Kerberos client might request. The AS sends the flags back to the client, thus allowing the client to match whether the AS can provide the optional features requested.
  • authtime: The time at which the AS issues the ticket.
  • starttime: The time at which the ticket becomes valid.
  • endtime: The time at which the ticket expires.
  • renew-till: The final expiry time of renewable tickets.
  • srealm: The server's realm.
  • sname: The name of the server for which the accompanying ticket is valid.
  • caddr: This field identifies a list of addresses from which the accompanying ticket can be used. The purpose of this field is to make it more difficult for hackers to use stolen tickets.

Listing 2 provides the ASN.1 class definitions for the TGT response message. Readers can map the different fields shown in Figures 3 and 4 with the class definitions in Listing 2.


Listing 2. The ASN.1 class definition of the TGT response message
   AS-REP ::=    [APPLICATION 11] KDC-REP
   KDC-REP ::=   SEQUENCE {
                 pvno[0]                    INTEGER,
                 msg-type[1]                INTEGER,
                 padata[2]                  SEQUENCE OF PA-DATA OPTIONAL,
                 crealm[3]                  Realm,
                 cname[4]                   PrincipalName,
                 ticket[5]                  Ticket,
                 enc-part[6]                EncryptedData
   }

   EncryptedData ::=   SEQUENCE {
               etype[0]     INTEGER, -- EncryptionType
               kvno[1]      INTEGER OPTIONAL,
               cipher[2]    OCTET STRING -- ciphertext
   }

   EncASRepPart ::=    [APPLICATION 25] EncKDCRepPart
   EncKDCRepPart ::=   SEQUENCE {
               key[0]                       EncryptionKey,
               last-req[1]                  LastReq,
               nonce[2]                     INTEGER,
               key-expiration[3]            KerberosTime OPTIONAL,
               flags[4]                     TicketFlags,
               authtime[5]                  KerberosTime,
               starttime[6]                 KerberosTime OPTIONAL,
               endtime[7]                   KerberosTime,
               renew-till[8]                KerberosTime OPTIONAL,
               srealm[9]                    Realm,
               sname[10]                    PrincipalName,
               caddr[11]                    HostAddresses OPTIONAL
   }

The request for a service ticket

On receipt of a TGT, the client authors a request for a service ticket, as shown in Figure 5. The request for a service ticket is very similar to the request for the TGT that I discussed in Figure 2. You can match all the fields in Figure 5 with corresponding fields from Figure 2. I just need to explain the padata field with special reference to a service ticket request.


Figure 5. The structure of a service ticket request message
The structure of a service ticket request message

The padata field is a sequence of PA-DATA structures; it contains authentication data. A request for a service ticket needs to send the TGT to the ticket. The padata field wraps the TGT in one of its PA-DATA structures.

Kerberos uses the padata field for various purposes; wrapping a TGT is only one of them. Therefore, Kerberos has defined different integer values to specify what type of data a PA-DATA structure wraps.

Figure 5 shows that the PA-DATA sequence contains just one PA-DATA structure, which consists of two sub-fields, namely padata-type and padata-value. Each PA-DATA structure in a padata sequence will contain these two fields.

padata-type is an integer value that specifies the type of data in the accompanying padata-value field. When the padata-value field wraps a TGT in a service ticket request, the value of the padata-type field will be 1.

The padata-value field is a string of bytes that contains the TGT. The string of bytes in the padata-value field is actually another Kerberos structure named KRB_AP_REQ (or AP-REQ for short) and also known as an authentication header.

The authentication header contains the TGT along with some other fields, as follows:

  • pvno: I've explained this field in our discussion of Figure 2.
  • message-type: This field contains an integer value (12) that identifies the KRB_TGS_REQ message.
  • ap-options: This is a list of options. The first option is reserved for future use. The second specifies that the accompanying TGT is encrypted using the session key wrapped inside the accompanying TGT. Because the TGS already knows the session key, it can use the key for decryption. The third option, when selected, specifies that the client is requesting mutual authentication.
  • ticket: The TGT itself.
  • authenticator: This is an encrypted structure that contains several fields that allow the client to demonstrate its knowledge of the session key and help the TGS to detect replay attacks. The authenticator appears in encrypted (cipher text) form in the authentication header. The client uses the session key to encrypt the authenticator. The fields of the authenticator structure are as follows:
    • authenticator-vno: Version number of the authenticator format. For Kerberos version 5, this field should specify 5.
    • crealm and cname: I explained these while discussing Figure 2.
    • cksum: A checksum or a hash value, calculated over the byte encoding of the req-body field shown in Figure 5. This field will allow the TGS to check the integrity of the request message. As this checksum resides inside a structure encrypted using the session key, so this field also demonstrates the client's knowledge of the session key.
    • cusec and ctime: These two fields together specify the client's time when the KRB_AP_REQ message was authored. The cusec field specifies the microsecond part of the time, while the ctime field specifies the date and time in milliseconds.
    • subkey: This is an optional field that the client can use to specify a key that it wants to use for subsequent communication with the server. In the mobile banking application, I will try to reduce the processing burden on the J2ME client and, therefore, will leave it to the server to decide about session and sub-session keys.
    • seq-number: An optional field that can contain a sequence number of the message to detect replay attacks.
    • authorization-data: An optional field that carries application-specific authorization data. I won't use this field in the mobile banking application.

Listing 3 provides the ASN.1 class definitions for the service ticket request message. Readers can map the different fields shown in Figure 5 with the class definitions of Listing 3.


Listing 3. The ASN.1 class definition of the service ticket request message
TGS-REQ ::=        [APPLICATION 12] KDC-REQ
KDC-REQ ::=        SEQUENCE {
           pvno[1]               INTEGER,
           msg-type[2]           INTEGER,
           padata[3]             SEQUENCE OF PA-DATA OPTIONAL,
           req-body[4]           KDC-REQ-BODY
}

PA-DATA ::=        SEQUENCE {
           padata-type[1]        INTEGER,
           padata-value[2]       OCTET STRING,
                         -- might be encoded AP-REQ
}

KDC-REQ-BODY ::=   SEQUENCE {
            kdc-options[0]       KDCOptions,
            realm[2]             Realm, -- Server's realm
                         -- Also client's in AS-REQ
            sname[3]             PrincipalName OPTIONAL,
            from[4]              KerberosTime OPTIONAL,
            till[5]              KerberosTime,
            rtime[6]             KerberosTime OPTIONAL,
            nonce[7]             INTEGER,
            etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
                         -- in preference order
            addresses[9]         HostAddresses OPTIONAL,
            enc-authorization-data[10]   EncryptedData OPTIONAL,
                         -- Encrypted AuthorizationData encoding
            additional-tickets[11]       SEQUENCE OF Ticket OPTIONAL
}

AP-REQ ::= [APPLICATION 14] SEQUENCE {
            pvno [0]        INTEGER,        -- indicates Version 5
            msg-type [1]    INTEGER,        -- indicates KRB_AP_REQ
            ap-options[2]   APOptions,
            ticket[3]       Ticket,
            authenticator[4]        EncryptedData
}

APOptions ::= BIT STRING {
            reserved (0),
            use-session-key (1),
            mutual-required (2)
}

Ticket ::= [APPLICATION 1] SEQUENCE {
            tkt-vno [0]     INTEGER,        -- indicates Version 5
            realm [1]       Realm,
            sname [2]       PrincipalName,
            enc-part [3]    EncryptedData
}

-- Encrypted part of ticket
EncTicketPart ::= [APPLICATION 3] SEQUENCE {
            flags[0]        TicketFlags,
            key[1]          EncryptionKey,
            crealm[2]       Realm,
            cname[3]        PrincipalName,
            transited[4]    TransitedEncoding,
            authtime[5]     KerberosTime,
            starttime[6]    KerberosTime OPTIONAL,
            endtime[7]      KerberosTime,
            renew-till[8]   KerberosTime OPTIONAL,
            caddr[9]        HostAddresses OPTIONAL,
            authorization-data[10]  AuthorizationData OPTIONAL
}

-- Unencrypted authenticator
Authenticator ::= [APPLICATION 2] SEQUENCE  {
            authenticator-vno[0]    INTEGER,
            crealm[1]               Realm,
            cname[2]                PrincipalName,
            cksum[3]                Checksum OPTIONAL,
            cusec[4]                INTEGER,
            ctime[5]                KerberosTime,
            subkey[6]               EncryptionKey OPTIONAL,
            seq-number[7]           INTEGER OPTIONAL,
            authorization-data[8]   AuthorizationData OPTIONAL
}

The response containing the service ticket

When the TGS receives the request for a service ticket, it issues one in response. The TGS response that wraps the service ticket is shown in Figure 6. You can match Figure 6 with Figure 3. You'll find that the fields shown in Figure 3 are the same as those shown in Figure 6, except that the ticket field of Figure 3 is a TGT, while the ticket field of Figure 6 is a service ticket.

Also note that, while authoring the encrypted portion of Figure 6, the KDC uses the session key that it has already exchanged with the client in previous messages. The service ticket wraps a sub-session key that the client will use for secure communication with the e-bank server.


Figure 6. The structure of a service ticket response from the TGS
The structure of a service ticket response from TGS

Listing 4 provides the ASN.1 class definitions for the service ticket response message. Readers can map the different fields shown in Figure 6 with the class definitions of Listing 4.


Listing 4. The ASN.1 class definition of the service ticket response message
   TGS-REP ::=   [APPLICATION 13] KDC-REP
   KDC-REP ::=   SEQUENCE {
                 pvno[0]                    INTEGER,
                 msg-type[1]                INTEGER,
                 padata[2]                  SEQUENCE OF PA-DATA OPTIONAL,
                 crealm[3]                  Realm,
                 cname[4]                   PrincipalName,
                 ticket[5]                  Ticket,
                 enc-part[6]                EncryptedData
   }

   EncryptedData ::=   SEQUENCE {
               etype[0]     INTEGER, -- EncryptionType
               kvno[1]      INTEGER OPTIONAL,
               cipher[2]    OCTET STRING -- ciphertext
   }

   EncTGSRepPart ::=   [APPLICATION 26] EncKDCRepPart
   EncKDCRepPart ::=   SEQUENCE {
               key[0]                       EncryptionKey,
               last-req[1]                  LastReq,
               nonce[2]                     INTEGER,
               key-expiration[3]            KerberosTime OPTIONAL,
               flags[4]                     TicketFlags,
               authtime[5]                  KerberosTime,
               starttime[6]                 KerberosTime OPTIONAL,
               endtime[7]                   KerberosTime,
               renew-till[8]                KerberosTime OPTIONAL,
               srealm[9]                    Realm,
               sname[10]                    PrincipalName,
               caddr[11]                    HostAddresses OPTIONAL
   }

The client's message to the e-bank's business logic server

Now the client has the service ticket, which it can send to the e-bank's business logic server. The client sends the message in Figure 7 to the e-bank's server. The message is intended to request that the server establish a new secure context with the client.


Figure 7. The structure of the message from Kerberos client to the e-bank's server
The structure of the message from Kerberos client to the e-bank's server

Recall that the purpose of this article is to demonstrate a secure J2ME-based mobile banking application. I am going to use the Generic Security Services API (GSS API, or just GSS for short) on the server side to provide security features to the e-bank's business logic server. GSS is a generic high-level security API that can work on top of different security technologies like Kerberos. (See Resources for more on GSS.)

I'll discuss the use of the GSS API in the e-bank's business logic server in the third article of this series. For the moment, just note that, like Kerberos, GSS is also an IETF standard. The IETF has defined a GSS wrapper for Kerberos messages from client to server and back. In order to use GSS on the server side, I must ensure that the GSS client is able to author and process GSS wrappers.

The label on the outer box in Figure 7 is InitialContextToken, which is actually the name of the GSS wrapper that wraps the message from a GSS client to a GSS server. Inside the InitialContextToken wrapper, the first field is named thisMech, which defines the security mechanism that GSS uses as the low-level security technology (Kerberos, in this case).

The second field inside the InitialContextToken box is labeled KRB_AP_REQ, which I've examined while discussing Figure 5. Recall from the earlier discussion that the KRB_AP_REQ structure wraps a ticket. That's why I can use this structure to wrap a service ticket and send the same to the e-bank server. Recall that the service ticket already contains the sub-session key.

Listing 5 provides the ASN.1 class definitions for the Kerberos client's message to the e-bank's business logic server. You can map the different fields shown in Figure 7 to the class definitions of Listing 5.


Listing 5. The ASN.1 class definition of the secure context request message from client to server
   InitialContextToken ::=
   [APPLICATION 0] IMPLICIT SEQUENCE {
           thisMech        MechType
                   -- MechType is OBJECT IDENTIFIER
                   -- representing "Kerberos V5"
           innerContextToken ANY DEFINED BY thisMech
                   -- contents mechanism-specific;
                   -- ASN.1 usage within innerContextToken
                   -- is not required
   }

   AP-REQ ::= [APPLICATION 14] SEQUENCE {
           pvno [0]        INTEGER,        -- indicates Version 5
           msg-type [1]    INTEGER,        -- indicates KRB_AP_REQ
           ap-options[2]   APOptions,
           ticket[3]       Ticket,
           authenticator[4]        EncryptedData
   }

   APOptions ::= BIT STRING {
           reserved (0),
           use-session-key (1),
           mutual-required (2)
   }

   Ticket ::= [APPLICATION 1] SEQUENCE {
           tkt-vno [0]     INTEGER,        -- indicates Version 5
           realm [1]       Realm,
           sname [2]       PrincipalName,
           enc-part [3]    EncryptedData
   }

   -- Encrypted part of ticket
   EncTicketPart ::= [APPLICATION 3] SEQUENCE {
           flags[0]        TicketFlags,
           key[1]          EncryptionKey,
           crealm[2]       Realm,
           cname[3]        PrincipalName,
           transited[4]    TransitedEncoding,
           authtime[5]     KerberosTime,
           starttime[6]    KerberosTime OPTIONAL,
           endtime[7]      KerberosTime,
           renew-till[8]   KerberosTime OPTIONAL,
           caddr[9]        HostAddresses OPTIONAL,
           authorization-data[10]  AuthorizationData OPTIONAL
   }

   -- Unencrypted authenticator
   Authenticator ::= [APPLICATION 2] SEQUENCE  {
           authenticator-vno[0]    INTEGER,
           crealm[1]               Realm,
           cname[2]                PrincipalName,
           cksum[3]                Checksum OPTIONAL,
           cusec[4]                INTEGER,
           ctime[5]                KerberosTime,
           subkey[6]               EncryptionKey OPTIONAL,
           seq-number[7]           INTEGER OPTIONAL,
           authorization-data[8]   AuthorizationData OPTIONAL
   }

The e-bank's response

When the e-bank's business logic server receives the message in Figure 7, it extracts the service ticket and decrypts the encrypted portion of the ticket to fetch the sub-session key. The client already possesses the same sub-session key. Therefore, both the server and the client can use this sub-session key to securely communicate with each other.


Figure 8. The structure of the e-bank's response to the Kerberos client
The structure of the e-bank's response to the Kerberos client

The e-bank's business logic server sends an acknowledgement message back to the client, as shown in Figure 8. The following are the fields that constitute the message shown in Figure 8:

  • pvno: I explained this field while discussing Figure 2.
  • msg-type: This is a message type identifier with an integer value of 14.
  • enc-part: The encrypted part of the message. The client will decrypt this encrypted data using the sub-session key. When decrypted, it reveals another structure with the following fields:
    • ctime and cusec: I explained these fields while discussing Figure 6.
    • subkey: This is an optional key that the server might send to the client. If the server sends this key to the client, this key will be used for subsequent secure communication between the client and the server (instead of the sub-session key).
    • seq-number: I explained this field while discussing Figure 5.

Listing 6 provides the ASN.1 class definitions for the e-bank's response to the Kerberos client. Readers can map the different fields shown in Figure 8 with the class definitions in Listing 6.


Listing 6. The ASN.1 class definition of the secure context response from server to client
   AP-REP ::= [APPLICATION 15] SEQUENCE {
           pvno [0]        INTEGER,        -- represents Kerberos V5
           msg-type [1]    INTEGER,        -- represents KRB_AP_REP
           enc-part [2]    EncryptedData
   }

   EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
           ctime [0]       KerberosTime,
           cusec [1]       INTEGER,
           subkey [2]      EncryptionKey OPTIONAL,
           seq-number [3]  INTEGER OPTIONAL
   }


Kerberos tickets

Before I conclude this article, I want to show the structure of the Kerberos tickets themselves. Figure 9 shows the structure of a Kerberos ticket.


Figure 9. The structure of a Kerberos ticket
The structure of a Kerberos ticket

It consists of eleven fields:

  • tkt-vno: The version of the ticket format. It is currently 5.
  • realm and sname: I explained these fields while discussing Figure 2. These two fields together specify the complete identifier of the server for which the ticket is valid. In the case of the TGT, these two fields identify the TGS. On the other hand, in the case of a service ticket, they specify the e-bank's business logic server.
  • enc-part: This is the confidential part of the ticket. This encrypted part, when decrypted, is another Kerberos structure that consists of several fields, as described below:
    • flags: This is the set of flags that I mentioned while discussing the kdc-options field in Figure 2. One of these flags is used to tell whether this is a TGT or a service ticket.
    • key: This is the session key (for a TGT) or the sub-session key (for a service ticket).
    • creal and cname: I explained these fields while discussing Figure 2.
    • transited: As mentioned earlier, different Kerberos servers working in different realms can forward tickets from one realm to another. This field specifies names of different realms involved in issuing this ticket. I don't need this feature in the mobile banking application.
    • authtime: This is the time at which the KDC authenticated the requesting client.
    • starttime and endtime: The ticket is valid from starttime till endtime.
    • renew-till: As already mentioned, Kerberos tickets might be renewable. Such tickets can contain this field, which specifies the ultimate expiration of the ticket. After this time, the ticket will not be renewable.
    • caddr: I explained this field while discussing Figure 4.

A look ahead: Designing the Kerberos client

In the remainder of this series, I'll build the Kerberos client that will provide security features to the mobile banking application. The main purpose of the Kerberos client will be to author and process the Kerberos messages detailed here. The client will be capable of authoring all the messages from the client to the ticket or e-bank's server (the messages shown in Figures 2, 5, and 7) and processing the messages coming back from server (the messages shown in Figures 3, 4, 6, 8, and 9).

The Kerberos client that I will develop will run on resource-constrained wireless devices. Therefore, the client will have a small footprint. My focus will be on efficient use of available device resources.

Security applications normally impose a heavy processing burden on device resources. In order to increase program efficiency, I will have to make some compromises on good object-oriented design practices. This is quite normal in heavy-lifting J2ME applications. The next two articles of this series will demonstrate how to accomplish this for the mobile banking application.


Summary

In this article, I have explained the usage model and security requirements of a mobile banking application. I have also described the sequence of Kerberos messages (along with Kerberos data formats) that results in the exchange of cryptographic keys for secure communication between a Kerberos client and an e-bank's server. I then briefly looked ahead to the J2ME Kerberos client that I am going to build in the next two articles of this series.

I hope that the material in this article will be informative to anyone interested in the details of how Kerberos messages work. I'll need all of this information as I progress through the rest of our series.


Resources

About the author

Faheem Khan is an independent software consultant specializing in enterprise application integration (EAI) and B2B solutions. Readers can reach Faheem at fkhan872@yahoo.com.

Comments



Trademarks

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=10880
ArticleTitle=Lock down J2ME applications with Kerberos, Part 1: Introducing Kerberos data formats
publish-date=10282003
author1-email=fkhan872@yahoo.com
author1-email-cc=