[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

keytab - MIT Keytab Binary File Format Encoder / Decoder

I have written a small keytab encoder / decoder module in ANSI C. The
package can be downloaded here:


Also, inlined below is a brief description of the keytab binary file
format. There are a few parts missing that I wasn't certain about. Perhaps
someone knows the answer to these questions?

1) What fields are in host byte order? It seems that everything is big
   endian except the 16 bit vno and and 16 bit keyblock key type?
2) What codeset are strings? Are they UTF-8 or locale dependant?
3) Are my assumptions about num_components correct: 1 for no service,
   2 with service?
4) Have I missed anything?

If people would like to try this on their keytab files the test1.c test
decodes, encodes a copy, and then decodes the copy. Please let me know
what you find.



The Kerberos Keytab Binary File Format
Michael B Allen <mba2000 ioplex.com>
Last updated: Tue May 2 20:51:41 EDT 2006

The MIT keytab binary format is not a standard format, nor is it
documentated anywhere in detail. It is however understood by several
Kerberos implementations including Heimdal and of course MIT and keytab
files are created by the ktpass.exe utility from Windows. So it has
established itself as the defacto format for storing Kerberos keys.

The following C-like structure definitions illustrate the MIT keytab

  keytab {
      uint16_t file_format_version; /* 0x502 */
      keytab_entry entries[*];
  keytab_entry {
      int32_t size;
      uint16_t num_components;
      counted_string realm;
      counted_string service; /* optional */
      counted_string name;
      uint32_t name_type;
      uint32_t timestamp;
      uint16_t vno; /* little endian */
      keyblock key;
      uint32_t vno32; /* big endian */
  counted_string {
      uint16_t length;
      uint8_t data[length];
  keyblock {
      uint16_t type;
      uint8_t length;
      uint8_t data[length];

The keytab file format begins with the 16 bit file_format_version which
at the time this document was authored is 0x502.

The file_format_version is immediately followed by an array of
keytab_entry structures which are prefixed with a 32 bit size indicating
the number of bytes that follow in the entry. Note that the size should be
evaluated as signed. This is because a negative value indicates that the
entry is in fact empty (e.g. it has been deleted) and that the negative
value of that negative value (which is of course a positive value) is
the offset to the next keytab_entry. Based on these size values alone
the entire keytab file can be traversed.

The size is followed by a 16 bit num_components field indicating the
number of string components that follow minus one. In practice this value
will be either 1 to indicate the realm and name follow or 2 to indicate
the realm, service, and name follow. Each component is a counted_string.

The realm, optional service, and name components are counted_strings. A
counted string is simply an array of bytes prefixed with a 16 bit
length. With a service principal of HTTP/quark.foo.net@FOO.NET the
service, name and realm would be "HTTP" "quark.foo.net" and "FOO.NET"

Following the string components is the name_type. This value is usually
1 unless ... ?

The 32 bit timestamp indicates the time the key was established for that
principal. The value represents the number of seconds since Jan 1, 1970.

The 16 bit vno field is the version number of the key. This value may
be overridden by the vno32 field described below.

The keyblock structure consists of a 16 bit value indicating the keytype
(e.g. 3 is des-cbc-md5, 23 is arcfour-hmac-md5, 16 is des3-cbc-sha1,
etc). This is followed by an 8 bit value indicating the length of the
key data that follows.

The last field of the keytab_entry struction is optional. If the size of
the keytab_entry indicates that there are bytes remaining a 32 bit value
representing the key version number follows. This value superceeds the
16 bit value preceeding the keyblock.