[461] in Kerberos
New Kerberos ticket proposal
daemon@TELECOM.MIT.EDU (Ted Anderson)
Thu Jul 28 15:17:18 1988
From: Ted Anderson <ota+@ANDREW.CMU.EDU>
To: kerberos@ATHENA.MIT.EDU
I'd like to suggest several changes to the Kerberos ticket format. The
original motivation for a format change was to increase the range of
specifiable ticket lifetimes, but once that can of worms is open, I'd like to
make some additional suggestions.
This is the current format, as I understand it, from the _Project Athena_
_Technical Plan, Section E.2.1, *Kerberos Authentication and Authorization*_
_*System*_, dated 21 Dec 1987:
ticket = {flags, namep, instancep, realmp, addressp, Ksession,
lifetime, time_seckkds, names, instances}Kskvno
where:
flags: 1 byte, unsigned: byte order of granter?
namep: >= 0 chars, null terminated string
instancep: >= 0 chars, null terminated string
realmp: >= 0 chars, null terminated string
addressp: 4 bytes, unsigned: IP address
Ksession: 8 bytes, unsigned
lifetime: 1 byte, unsigned: in 5 minute intervals
time_seckkds: 4 bytes, unsigned: time issued, sec since 0000 GMT 1/1/70
names: >= 0 chars, null terminated string
instances: >= 0 chars, null terminated string
Kskvno: the server's (kvno'th) key, which encrypts the ticket
Accompanying the ticket, but not actually part of it are two additional fields:
a two byte unsigned length and a one byte key version number (kvno).
First several questions.
The purpose of the kvno is not explained. The paper uses kvno as a subscript
on keys which are used for encrypting tickets. From this, and some later
discussion about changing master passwords, I gather it serves to distinguish
between tickets encrypted with an old password and those encrypted with the new
password. Is this right? Is this the only use envisioned for this field?
What is the flags field used for? I found one place in the Kerberos document
revision history that suggested it was used to specify the byte order of the
ticket granter. Is this still true? Are any of the other bits used for
anything?
The current definition appears to allow for a zero length principal name. Is
this intentional or useful?
What is the purpose of including the server's name/instance in the ticket?
These are potentially lengthy strings which could contribute significantly to
the encryption/decryption time and contain very minimal information. Surely a
server with the correct key would know its own name. The only thing I can
think of that that it would provide a final check against a ticket that had
been tampered with. It seems an expensive way of accomplishing this. Am I
missing something?
Here is an alternative ticket proposal:
ticket = {kvno, {flags, Ksession, namep, instancep, realmp, addressp,
starttime, endtime, label}Kskvno}
where these fields are different from the above:
kvno: 1 byte: identifies the encryption key to the server
Ksession: 8 byte sequence
namep: > 0 chars, null terminated string
starttime: 4 bytes: time ticket becomes valid
endtime: 4 bytes: time ticket expires
label: >= 2 chars: a string to verify correct decryption
Comments/Rationale:
I propose limiting principal names to upper and lower case letters, digits,
underscore, apostrophe, and hyphen. The length must be between 1 and 63
characters plus a trailing null. Instance and realm strings would be
restricted to the same character set with the addition of dot (mainly for
Internet domain names) and lengths of between 0 and 63 characters plus a null.
The motivation for the length limitation is to bound the size of the largest
ticket (the minimum length is 33 bytes, the maximum would be 217). This will
simplify allocation procedures and codify the maximum length, which many
implementation are likely to impose anyway.
The length limit of 63 characters is fairly arbitrary. The selection of a
length should ideally accommodate very nearly all the envisioned uses.
Certainly, the vast majority of user's names will fit in 63 characters. Indeed
31 would probably be enough, although the trend lately towards hyphenated names
may push this limit. Realms and in some cases instances have been named after
domain names so their length is a consideration. RFC-1035 specifies a limit of
63 characters on the individual components of a domain name, but the whole name
may be as long as 255 characters. This could cause trouble, but 63 characters
will probably be sufficient in practice. The limit on realms could be
increased to 255 but this seems excessive.
The character set restrictions are the same as those ``strongly recommended''
for domain names [RFC-1035] with the addition of underscore, and apostrophe.
These graphics allow the following representations for some of the more exotic
names that might be encountered: Du_Pont, D'Urfey, Dvora'k (which omits the
miniature, raised 'v' over the 'r'), de_Soto, Dore' (where the apostrophe
following a letter indicates an accent over the letter). Other possible
additions include ':' following a letter to stand for an umlaut, and backquote
following a letter to indicate accent grave. Internet domain names are case
insensitive, whereas, names, instances, and realms are case sensitive. A
standard needs to be established for selecting the name of a realm from the
various case representations of the corresponding domain name. Alternatively,
realms (and perhaps instances) could be made case insensitive.
I suggest using network byte order for constructing tickets and that the bits
of the flags field be reserved for future use and set to zero by current
implementations. The Internet standard for byte order is specified in RFC-791:
Internet Protocol, appendix B: Data Transmission Order, and is strictly
big-endian. At the byte level, which is the most important for machines with
byte addressing, the order is left to right for strings, and most significant
to least significant for multi-byte integers. Note that the session key is a 8
byte sequence, not a 64 bit integer.
In spite of the fact that this ordering may not be the most convenient for all
machines, utilizing a standard for communications has several advantages.
First, the Internet standard is already in wide use for inter-machine
communication so adhering to a well known standard will minimize confusion
about byte order. Second, from a conceptual point of view, it will be simpler
for implementors to uniformly convert into network order when assembling a
ticket and out of network order when disassembling them. This eliminates
checking the flags bit and having code that handles both cases. The cost of
conversion to and from network order is small enough that the savings realized
in cases where the natural ordering at the sender and receiver is the same is
not worth the added complexity.
I suggest that kvno be used by the server to identify the key needed to decrypt
a ticket. This will work for the case of a transition period where some
outstanding tickets are encrypted with an old password. In addition, it
smoothly handles the case of a server which maintains several passwords. An
example of where this would be useful is the case of Kerberos servers in a
multiple, independent realm environment. Each Kerberos ticket granting server
exchanges a password with the Kerberos in each cooperating realm. This
password is used to encrypt tickets that authenticate its users to the other
Kerberos. For safety reasons the password exchanged with another realm should
not be the same as the password used locally. Thus a ticket received by a
Kerberos server may be encrypted by either the local password or an external
password. In general, to provide security firewalls in a large multi-realm
environment there may be many external passwords known to a server, although
each Kerberos will only need to remember one for each server. Other reasons
why a server might encounter tickets encrypted with different passwords can be
imagined. The kvno field allows a simple method for discriminating between
such tickets.
The argument for including the kvno as an unencrypted part of the ticket is
that the ticket is effectively useless without the kvno. Thus, it is
conceptually simpler, to treat the ticket as a single entity where only the
encryption routines know which part is encrypted.
The use of both a start time and end time provides the most flexible means for
controlling ticket lifetimes. These times should be checked for reasonability
by making sure the starttime is in the past, the endtime is in the future, and
The difference between the two is strictly positive but less than some
reasonable upperbound. The upperbound should allow lifetimes of at least one
year. An alternative is to provide a start time with a duration, which could
be specified as a two byte unsigned number of minutes. This allows the
specification of lifetimes less than 45 days long. The advantage of the
start/end method is that the ticket format
does not impose precision or length limitations of the specification of
lifetimes. Thus the simplicity and flexibility more than compensate for the
small additional cost in ticket length.
From a cryptographic standpoint, putting the most random part of the ticket at
the beginning makes attempts to decrypt it more difficult because of the use of
cipher-block-chaining during encryption. This also means that interference
with a ticket is most likely to garble the end of the ticket. Since the order
of fields in the ticket is arbitrary it would be advantageous to put the
session key near the beginning and an easily recognized label at the end.
Leaving the flags at the very beginning allows the possibility of using it to
support a later incompatible format change.
This ticket proposal eliminates the name and instance of the server from the
ticket. This should provide a substantial reduction in the length, and
corresponding encryption and decryption times, of tickets. The absence of the
server's identity from the ticket could only cause confusion if a user supplies
some other ticket to a server. In almost every case this error would be
detected because the key used by the server to decrypt the ticket would be
wrong and result in total garbage. If a server's password has been
compromised, a user could forge tickets at will, and all would be lost anyway.
The only other alternative is that two servers coincidentally selected the same
password and their tickets are inadvertently switched by the user. In this
exceedingly unlikely case the user is still correctly authenticated to the
server and no security violation occurs. Thus, naming the server for which a
ticket is created is entirely unnecessary.
Using the server's name and instance as the ticket's label is also
questionable. To detect decryption errors I suggest, in addition to
reasonability checks on all the fields in the ticket, padding the end with a
constant string. Since the encryption algorithm requires its input to be a
multiple of 8 bytes, adding at least two characters and enough more to bring
the length to this boundary would allow this extra correctness check with a
minimum of overhead. Specifically, if the length of the part to be encrypted
is N; append the first 9-(N+1)%8 characters of the string "TicketEnd" to the
ticket before encryption. Checking for this terminal sequence after decryption
provides added confidence in the integrity of the ticket.