Key derivation with non-ASCII characters

Frank Taylor FrankSTaylor at gmail.com
Wed Sep 8 09:14:38 EDT 2004


> Could you look at the salt that is being used?  The easiest way to do
> that is to try sending an AS request and see what you get back in the
> etype-info structure?


I have done some investigation now and have the following information.

The Active Directory Domain (Kerberos realm) is DEV.PROPERO.INT. It is
running Windows 2003 Active Directory.

The account in question is "paeuser1" with password "secret£" (secret
following by a pound sterling (0x00a3 in Unicode)). The account
requires pre-authentication. Logging into a domain-connected Windows
client PC works. Performing an LDAP bind (from Java) to AD using this
username and password also works. Therefore the password really is
what we expect.

The client code is jKrb5 (from
http://www.mit.edu/afs/athena/astaff/project/krb5/raeburn/jkrb5 with a
few fixes and additions).

References:

   crypto spec: draft-ietf-krb-wg-crypto-07.txt
   kerberos spec: draft-ietf-krb-wg-kerberos-clarifications-06.txt


1) Confirming the salt

Sending a non-preauthenticated AS_REQ message results in a KRB_ERROR
message of type KDC_ERR_PREAUTH_REQUIRED. The associated e-data
contains a sequence of PA-DATAs as follows:

  Type  Name                  Value

   11   pa-etype-info         etype=1, salt="DEV.PROPERO.INTpaeuser1"
   2    pa-enc-timestamp      No data (e-data block is 0 length)
   15   ???                   No data (e-data block is 0 length)

Ethereal shows the following KRB-ERROR e-data block (starting at
position 0x94):

0090  4e 54 ac 49 04 47 30 45  30 2d a1 03 02 01 0b a2   NT.I.G0E
0-......
00a0  26 04 24 30 22 30 20 a0  03 02 01 01 a1 19 04 17   &.$0"0 .
........
00b0  44 45 56 2e 50 52 4f 50  45 52 4f 2e 49 4e 54 70   DEV.PROP
ERO.INTp
00c0  61 65 75 73 65 72 31 30  09 a1 03 02 01 02 a2 02   aeuser10
........
00d0  04 00 30 09 a1 03 02 01  0f a2 02 04 00            ..0.....
.....


So, without understanding the other e-data PA-DATA elements, it seems
that the default salt is correct: DEV.PROPERO.INTpaeuser1.


2) Confirm the string_to_key being used

A test harness for the string_to_key() function has been developed to
test that the function is operating correctly (according to the crypto
spec).

Three string_to_key functions were tested:

   1 Original (the original jKrb5 function modified to use UTF-8
               password to bytes encoding)

   2 Boolean[64] (a direct re-implementation of the original function
                  using arrays of booleans instead of Java longs for
                  the bit manipulation. This includes the various left
                  and right shift operations from the original
                  implementation.)

   3 Boolean[56] (a direct implementation of the spec using arrays of
                  booleans for the bit manipulation. Instead of
                  working on 64 bits, this implementation follows the
                  spec precisely and only operates on 56 bit
                  bitstrings.)

Note: The left and right shifts in the original string_to_key()
puzzled me for a while as they are not in the spec. However, it is
clear that they are just a optimisation of the algorithm.

During the tests, all three algorithms give exactly the same output,
so I'll only give results for the original algorithm.

Four sample results are used (the full source is shown: password +
realm + username):


1 Simple password

RESULT -----------------------------------------------------
RESULT Password:  secretDEV.PROPERO.INTpaeuser1
RESULT Bytes:     73 65 63 72 65 74 44 45 56 2e 50 52 4f 50 45 52 4f
2e 49 4e 54 70 61 65 75 73 65 72 31
RESULT Method:    Original
RESULT Generated: 40d586a1d51f6294
RESULT Wanted:    40d586a1d51f6294
RESULT Outcome:   PASS
RESULT -----------------------------------------------------


2 Pound sign in password

RESULT -----------------------------------------------------
RESULT Password:  secret<A3>DEV.PROPERO.INTpaeuser1
RESULT Bytes:     73 65 63 72 65 74 c2 a3 44 45 56 2e 50 52 4f 50 45
52 4f 2e 49 4e 54 70 61 65 75 73 65 72 31
RESULT Method:    Original
RESULT Generated: 76f72392310e62bc
RESULT Wanted:    202ba9bfe70ad37 (from ktpass)
RESULT Outcome:   FAIL
RESULT -----------------------------------------------------


3 Simple test case from crypto spec

RESULT -----------------------------------------------------
RESULT Password:  passwordATHENA.MIT.EDUraeburn
RESULT Bytes:     70 61 73 73 77 6f 72 64 41 54 48 45 4e 41 2e 4d 49
54 2e 45 44 55 72 61 65 62 75 72 6e
RESULT Method:    Original
RESULT Generated: cbc22fae235298e3
RESULT Wanted:    cbc22fae235298e3
RESULT Outcome:   PASS
RESULT -----------------------------------------------------


4 Complex test case from crypto spec: "<A7>ATHENA.MIT.EDUJuri?i?"

RESULT -----------------------------------------------------
RESULT Password:  <A7>ATHENA.MIT.EDUJuri?i?
RESULT Bytes:     c3 9f 41 54 48 45 4e 41 2e 4d 49 54 2e 45 44 55 4a
75 72 69 c5 a1 69 c4 87
RESULT Method:    Original
RESULT Generated: 62c81a5232b5e69d
RESULT Wanted:    62c81a5232b5e69d (from crypto spec)
RESULT Outcome:   PASS
RESULT -----------------------------------------------------


3) Windows ktpass

Using ktpass.exe on Windows I generated the following keys:

   1 Simple password: 0x40d586a1d51f6294
   2 Pound sign in password: 0x0202ba9bfe70ad37
   3 Simple test case from crypto spec: 0xcbc22fae235298e3
   4 Complex test case from crypto spec: 0xe65d5238b96bf245

Note: In case 4, I'm not sure I was able to pass ktpass.exe the right
characters... I created a batch file (saved in UTF-8 encoding) that
used variables to substitute the username and password on the command
line. I used the Character Map utility to enter the characters into
the batch file in the first place.

In both cases where non-7-bit-ASCII characters are used ktpass.exe
generates a different key from the MIT standard.


4) MIT Kerberos 1.3.4

Running MIT Kerberos 1.3.4 from Linux with the paeuser1/secret£
combination also failed.

Note: I could not type a pound sign on the command line, but could
edit a file containing one, using it as follows:

    ditty:bin$ ./kinit -V paeuser1 at DEV.PROPERO.INT < password
    Password for paeuser1 at DEV.PROPERO.INT: 
    kinit(v5): Preauthentication failed while getting initial
credentials


5) Summary

It seems that our client code is correct w.r.t. to the draft Kerberos
and crypto specs, however MS AD is producing/expecting different keys
for non-7-bit-ASCII passwords even though the salt is the same.

Any ideas on where to go next?

Thanks,

Frank.


More information about the Kerberos mailing list